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
|