Pickle to source code

Jean-Paul Calderone exarkun at divmod.com
Wed Oct 26 16:11:29 CEST 2005


On 26 Oct 2005 06:15:35 -0700, Gabriel Genellina <gagenellina at softlab.com.ar> wrote:
>> I want to convert from pickle format to python source code. That is,
>> given an existing pickle, I want to produce a textual representation
>> which, when evaluated, yields the original object (as if I had
>> unpickled the pickle).
>> I know of some transformations pickle/xml (Zope comes with one such
>> tool, gnosis xml is another) so I believe I could build something based
>> on them.
>> But I dont want to reinvent the wheel, I wonder if anyone knows of a
>> library which could do what I want?
>
>An example to make things clear:
>
>class MyClass:
>    def __init__(self,a,b):
>        self.a=a
>        self.b=b
>    def foo(self):
>        self.done=1
># construct an instance and work with it
>obj = MyClass(1,2)
>obj.foo()
># save into file
>pickle.dump(obj,file('test.dat','wb'))
>
>Then, later, another day, using another process, I read the file and
>want to print a block of python code equivalent to the pickle saved in
>the file.
>That is, I want to *generate* a block of code like this:
>
>xxx = new.instance(MyClass)
>xxx.a = 1
>xxx.b = 2
>xxx.done = 1
>
>Or perhaps:
>
>xxx = new.instance(MyClass, {'a':1,'b':2,'done':1})
>
>In other words, I need a *string* which, being sent to eval(), would
>return the original object state saved in the pickle.
>As has been pointed, repr() would do that for simple types. But I need
>a more general solution.
>
>The real case is a bit more complicated because there may be references
>to other objects, involving the persistent_id mechanism of pickles, but
>I think it should not be too difficult. In this example, if xxx.z
>points to another external instance for which persistent_id returns
>'1234', would suffice to output another line like:
>xxx.z = external_reference('1234')
>
>I hope its more clear now.

You may find twisted.persisted.aot of some use.  Here is an example:

>>> class Foo:
...     def __init__(self, x, y):
...             self.x = x
...             self.y = y
...
>>> a = Foo(10, 20)
>>> b = Foo('hello', a)
>>> c = Foo(b, 'world')
>>> a.x = c
>>> from twisted.persisted import aot
>>> print aot.jellyToSource(a)
app=Ref(1,
  Instance('__main__.Foo',
    x=Instance('__main__.Foo',
      x=Instance('__main__.Foo',
        x='hello',
        y=Deref(1),),
      y='world',),
    y=20,))
>>> 

AOT is unmaintained in Twisted, and may not support some newer features of Python (eg, datetime or deque instances).  If this seems useful, you may want to contribute patches to bring it up to the full level of functionality you need.

Jp



More information about the Python-list mailing list