[mod_python] object type. why it not works?

Jeff Hinrichs - DM&T jeffh at dundeemt.com
Sun Jun 24 23:05:09 EDT 2007


On 6/24/07, Graham Dumpleton <graham.dumpleton at gmail.com> wrote:
> On 24/06/07, Jeff Hinrichs - DM&T <jeffh at dundeemt.com> wrote:
> > On 6/23/07, ziapannocchia at gmail.com <ziapannocchia at gmail.com> wrote:
> > > I have a selfmade apache server, and I'm writing  a little web
> > > application with mod python.
> > >
> > > Using this def:
> > >
> > > def testPython(contenuto):
> > >   test="test"
> > >   return type(test)
> > >
> > > I obtain this error:
> > >
> > > Mod_python error: "PythonHandler mod_python.publisher"
> > >
> > > Traceback (most recent call last):
> > >
> > >   File "/usr/lib64/python2.4/site-packages/mod_python/apache.py", line
> > > 299, in HandlerDispatch
> > >     result = object(req)
> > >
> > >   File "/usr/lib64/python2.4/site-packages/mod_python/publisher.py",
> > > line 213, in handler
> > >     published = publish_object(req, object)
> > >
> > >   File "/usr/lib64/python2.4/site-packages/mod_python/publisher.py",
> > > line 412, in publish_object
> > >     return publish_object(req,util.apply_fs_data(object, req.form, req=req))
> > >
> > >   File "/usr/lib64/python2.4/site-packages/mod_python/publisher.py",
> > > line 412, in publish_object
> > >     return publish_object(req,util.apply_fs_data(object, req.form, req=req))
> > >
> > >   File "/usr/lib64/python2.4/site-packages/mod_python/util.py", line
> > > 401, in apply_fs_data
> > >     fc = object.__init__.im_func.func_code
> > >
> > > AttributeError: 'wrapper_descriptor' object has no attribute 'im_func'
> > >
> > > Instead, on command line, the same istruction works well:
> > >
> > > cloc3 at s939 /home/cloc3 $ python
> > > Python 2.4.4 (#1, May 18 2007, 08:25:49)
> > > [GCC 4.1.2 (Gentoo 4.1.2)] on linux2
> > > Type "help", "copyright", "credits" or "license" for more information.
> > > >>> test="test"
> > > >>> type(test)
> > > <type 'str'>
> > >
> > >
> > > What may be wrong?
> >
> > Publisher wants to return a string -- and you are attempting to return
> > an object, http://docs.python.org/lib/bltin-type-objects.html
> >
> > try, return test  --or-- return str(type(test))
>
> Actually, you are supposed to be able  to return anything from a
> published function which can be converted to a string. Thus one can
> return integers, dictionaries, lists, or custom data types provided
> they defined a __str__() method.
>
> Now, there is actually a problem here and it derives from fact that
> publisher does something that I didn't even realise. Question is
> whether it is an inadvertent feature added by accident or whether it
> was intentional.
>
> The problem is with the function:
>
> def publish_object(req, object):
>     if callable(object):
>
>         # To publish callables, we call them an recursively publish the result
>         # of the call (as done by util.apply_fs_data)
>
>         req.form = util.FieldStorage(req, keep_blank_values=1)
>         return publish_object(req,util.apply_fs_data(object, req.form, req=req))
>
>     else:
>        ...
>
> The intent of this function is that it is called with the object which
> the URL got matched to. If the target wasn't callable then resulted
> would be that it gets converted to a string and written back as
> response.
>
> If the target was callable, then util.apply_fs_data() is called to
> actually make the call against the target object. The result of this
> is then passed back into publish_object() in a second call to have the
> resulted converted to a string and written back as response.
>
> Problem is that in calling publish_object() a second time, if the
> result of calling util.apply_fs_data() was itself a callable, then a
> subsequent attempt will be made to call that.
>
> At this point I am going to assume that this wasn't intentional, and
> if it was then it has a bug for other reasons besides what is being
> seen. Namely, it creates an instance of util.FieldStorage on every
> call and assigns it to req.form. This means that form data would get
> wiped on a recursive call to a second callable object. If the feature
> was intentional, then it should check to see if req.form exists and
> use it rather than creating util.FieldStorage.
>
> So, there are a few issues here that need to be sorted out.
>
> 1. Should publisher invoke a callable object returned by a function.
>
> 2. If answer to 1 is yes, then how form data is managed needs to be fixed.
>
> 3. If answer to 1 is yes, then before recursively calling a callable
> then publisher should apply its rule set to ensure it isn't calling an
> object type it isn't supposed to.
>
> In respect of 3, if one has:
>
>   index = type("test")
>
> then accessing index will result in Forbidden response as rule set
> denies access, not so with the recursive call though.
>
> Anyone got any opinions on whether publisher should do 1?
>
> Graham
>

Graham,

If it is a bug, it's been around for some time (at least 3.1).  I
don't have a problem with it expecting the return variable to be
flattenable to a string.  However, vampire works as you intended -- I
believe.

vampire returns
  <type 'str'>

for:
class Callable:

    def test(self,req):

        t = "test"

        return type(t)



callable = Callable()


So, I would vote for 1, because it was how publisher was intended
before this unnoticed "bug" was found.  Personally, I'm in favor of
replacing publisher with vampire -- why hasn't that happened? vampire
does everything publisher does, in my experience, and then does the
other things I need/want.

Ziapannocchia -- you should check the vampire module out.
http://www.dscpl.com.au/projects/vampire/  Not to dump on publisher -
but vampire offers some real advantages over the stock publisher.
Graham did a bang up job on it. (Thanks Graham)

-Jeff


More information about the Mod_python mailing list