[mod_python] Pickle can't save classes instances in mod_python ?

Eric Baumer ebaumer at ics.uci.edu
Wed Jul 30 17:34:49 EDT 2008


I was having trouble loading a pickled class object using mod_python 
when I came across this post in the mod_python archives from June 2007. 
even though the link below implies that loading a pickled object in this 
manner cannot be done, I believe I may have found a work around. I 
wanted to bounce this off the mod_python list for two reasons: (a) to 
make sure I'm not breaking anything, and (b) to share what may be a 
viable solution to this problem.

the link mentioned here seems to imply that one cannot load a pickled 
instance of a class in a script running through mod_python. the problem 
seems to be related to mod_python's method of importing. since there 
doesn't seem to be a good way to guarantee where on the file system the 
script will run when apache receives a request that invokes mod_python. 
thus, rather than referring to a module by name alone (with the standard 
"import module_name" approach), modules are referred to by their path on 
the file system using apache.import_module, for example "my_module = 
apache.import_module('/home/username/my_proj/my_module.py')".

the problem becomes that this method of importing doesn't register the 
module name with sys.modules. therefore, if I have a pickled instance of 
some class my_module.MyClass, when I try to load the pickled instance, 
python would complain that there is "No module named my_module" (as 
described by the OP), even if I had loaded it using apache.import_module.

the workaround that I found looks something like the following.

import sys
def index(req):
    my_module = apache.import_module('/home/username/my_proj/my_module.py')
    sys.modules['my_module'] = my_module

this code ensures that my_module is registered with the list of modules 
python knows about in sys.modules, so that when I load that pickled 
instance of my_module.MyClass, python knows about a module named 
"my_module" and thus can properly load the class.

I should note that, in practice, this has actually worked for me. 
whether or not it's a good idea, though, is another question.

what do you all think? have I gone horribly wrong, or is this a viable 
work around to loading a pickled instance of a class?

~Eric



>> >/ Read:
>> />/
>> />/   http://www.dscpl.com.au/wiki/ModPython/Articles/IssuesWithSessionObjects
>> />/
>> />/ Although document was written in reference to sessions, they use
>> />/ pickle and thus it still applies.
>> />/
>> />/ Graham
>> /
>> Ok, that's a limitation, but I'll now I understand what happened  !
>>
>> Thanks !
>>
>> Seb
> Hello !
>
> I've found something a bit strange in mod_python : the pickle
> instruction doesn't work when we want to save classes ( there is no
> problème with tupple or list.. )
>
> I made this code for explain it:
>
> -->
> import mod_python
> import pickle
>
> #Create a very simple class object
> class another_class:
>
>        def __init__(self, text):
>                self.text =     text
>
> #Another one class
> class a_class:
>
>        def __init__(self):
>                self.elements = []
>
>                #Add an element of the second class
>                self.add_entry("test")
>                self.save()
>
>        def add_entry(self, name):
>                self.elements.append( another_class(name) )
>
>        def save(self):
>                #Try to save it with pickle.. works but
>                result = pickle.dumps(self.elements)
>                #We can't load the data after !
>                self.elements = pickle.loads(result)
>
> #If all works good, send a message
> def handler(req):
>        req.write( 'ok' )
>        return(mod_python.apache.OK)
>
> #We run this class outside any mod_python event
> my_class = a_class()
> <--
>
> And here is the result :
>
> -->
> MOD_PYTHON ERROR
>
> ProcessId:      5104
> Interpreter:    'localhost.localdomain'
>
> ServerName:     'localhost.localdomain'
> DocumentRoot:   '/var/www/'
>
> URI:            '/~sebastien/test/'
> Location:       None
> Directory:      '/home/sebastien/public_html/test/'
> Filename:       '/home/sebastien/public_html/test/'
> PathInfo:       ''
>
> Phase:          'PythonHandler'
> Handler:        'handler'
>
> Traceback (most recent call last):
>
>  File "/usr/lib/python2.4/site-packages/mod_python/importer.py", line
> 1537, in HandlerDispatch
>    default=default_handler, arg=req, silent=hlist.silent)
>
>  File "/usr/lib/python2.4/site-packages/mod_python/importer.py", line
> 1202, in _process_target
>    module = import_module(module_name, path=path)
>
>  File "/usr/lib/python2.4/site-packages/mod_python/importer.py", line
> 296, in import_module
>    log, import_path)
>
>  File "/usr/lib/python2.4/site-packages/mod_python/importer.py", line
> 680, in import_module
>    execfile(file, module.__dict__)
>
>  File "/home/sebastien/public_html/test/handler.py", line 35, in ?
>    my_class = a_class()
>
>  File "/home/sebastien/public_html/test/handler.py", line 18, in __init__
>    self.save()
>
>  File "/home/sebastien/public_html/test/handler.py", line 27, in save
>    self.elements = pickle.loads(result)
>
>  File "pickle.py", line 1394, in loads
>    return Unpickler(file).load()
>
>  File "pickle.py", line 872, in load
>    dispatch[key](self)
>
>  File "pickle.py", line 1083, in load_inst
>    klass = self.find_class(module, name)
>
>  File "pickle.py", line 1138, in find_class
>    __import__(module)
>
> ImportError: No module named _mp_e3b5c44c50230d33c470783bc2809f23
>
>
> MODULE CACHE DETAILS
>
> Accessed:       Thu Jun 14 22:49:06 2007
> Generation:     3
>
> _mp_e3b5c44c50230d33c470783bc2809f23 {
>  FileName:     '/home/sebastien/public_html/test/handler.py'
>  Instance:     3 [RELOAD]
>  Generation:   3 [ERROR]
>  Modified:     Thu Jun 14 22:48:49 2007
>  Imported:     Thu Jun 14 22:37:06 2007
> }
> <--
>
> When I launch this program inside a terminal, all works fine, there
> are no error message, so I don't understand what happend..
>


-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mm_cfg_has_not_been_edited_to_set_host_domains/pipermail/mod_python/attachments/20080730/76c75ce5/attachment.html


More information about the Mod_python mailing list