Hello everyone,

I am trying to serialize a function, class, etc and transfer it, have it unserialized and used. The thing is that this code is not defined on the receiving side and thus it does not work. I tried the following tests:

Terminal A:

>>> import pickle
>>> def test(): pass
...
>>> pickle.dumps(test)
'c__main__\ntest\np0\n.'
>>>

Terminal B:

>>> import pickle
>>> pickle.loads('c__main__\ntest\np0\n.')
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
 File "/usr/lib/python2.5/pickle.py", line 1374, in loads
   return Unpickler(file).load()
 File "/usr/lib/python2.5/pickle.py", line 858, in load
   dispatch[key](self)
 File "/usr/lib/python2.5/pickle.py", line 1090, in load_global
   klass = self.find_class(module, name)
 File "/usr/lib/python2.5/pickle.py", line 1126, in find_class
   klass = getattr(mod, name)
AttributeError: 'module' object has no attribute 'test'


Ok, so pickle needs the code to be defined on both sides, so I tried marshal:

Terminal A:

>>> import marshal
>>> marshal.dumps(test)
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
ValueError: unmarshallable object

Ok, as the docs say, marshal is quite limited, no functions or user classes can be marshalled, I did get it to work like this though :

>>> import inspect
>>> marshal.dumps(inspect.getmembers(test, inspect.iscode)[0][1])
'c\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00C\x00\x00\x00s\x04\x00\x00\x00d\x00\x00S(\x01\x00\x00\x00N(\x00\x00\x00\x00(\x00\x00\x00\x00(\x00\x00\x00\x00(\x00\x00\x00\x00s\x07\x00\x00\x00<stdin>t\x04\x00\x00\x00test\x01\x00\x00\x00s\x00\x00\x00\x00'

ok, but can I unmarshal it?

Terminal B:

>>> marshal.loads('c\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00C\x00\x00\x00s\x04\x00\x00\x00d\x00\x00S(\x01\x00\x00\x00N(\x00\x00\x00\x00(\x00\x00\x00\x00(\x00\x00\x00\x00(\x00\x00\x00\x00s\x07\x00\x00\x00<stdin>t\x04\x00\x00\x00test\x01\x00\x00\x00s\x00\x00\x00\x00')
<code object test at 0xb7591578, file "<stdin>", line 1>

ok, it seams to work...

>>> marshal.loads('c\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00C\x00\x00\x00s\x04\x00\x00\x00d\x00\x00S(\x01\x00\x00\x00N(\x00\x00\x00\x00(\x00\x00\x00\x00(\x00\x00\x00\x00(\x00\x00\x00\x00s\x07\x00\x00\x00<stdin>t\x04\x00\x00\x00test\x01\x00\x00\x00s\x00\x00\x00\x00')()
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
TypeError: 'code' object is not callable

ok, logical, it's a code object...

>>> eval(marshal.loads('c\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00C\x00\x00\x00s\x04\x00\x00\x00d\x00\x00S(\x01\x00\x00\x00N(\x00\x00\x00\x00(\x00\x00\x00\x00(\x00\x00\x00\x00(\x00\x00\x00\x00s\x07\x00\x00\x00<stdin>t\x04\x00\x00\x00test\x01\x00\x00\x00s\x00\x00\x00\x00'))

ok, this works, not super pretty, but it works

now user objects?

>>> class A(object): pass
...
>>> a = A()
>>> marshal.dumps(a)
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
ValueError: unmarshallable object

ok, expected...

>>> inspect.getmembers(a, inspect.iscode)
[]

ok, not cool, can't use the previous method...


Ok, now a word about what I'm trying to do, I'm trying to run python code in a new process, like multiprocessing does, but without multiprocessing. I'm trying to serialise the code because I 'd like to do something like:

pseudo-code, serialize/unserialize/process are made up:

def newProcess(func, *args, **kwargs):
   func = serialize(func)
   args = serialize(args)
   kwargs = serialize(kwargs)
process("python -c 'import serialize, unserialize;print serialize(unserialize(\'%s\')(*unserialize(\'%s\'), **unserialize(\'%s\')))'" % (func, args, kwargs))
  #read result from stdout

I'm greatly simplifying this because I'm using a framework, but that's the basic idea.

thanks,
Gabriel




--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to