[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/'