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
|