[Python-Dev] How to spell PyInstance_NewRaw in py3k?

Alexander Belopolsky alexander.belopolsky at gmail.com
Mon Jun 28 21:59:00 CEST 2010


Issue #5180 [1] presented an interesting challenge: how to unpickle
instances of old-style classes when a pickle created with 2.x is
loaded in 3.x python?  The problem is that pickle protocol requires
that unpickled instances be created without calling the __init__
method.   This is necessary because pickle file may not contain
information about how __init__ method should be invoked.  Instead,
implementations are required to bypass  __init__ and populate
instance's __dict__ directly using data found in the pickle.

Pure python implementation uses the following trick that happens to work in 3.x:

class Empty:
    pass

pickled = Empty()
pickled.__class__ = Pickled

This of course, creates a new-style class in 3.x, but if 3.x version
of Pickled behaves similarly to its 2.x predecessor, it should work.

The cPickle implementation, on the other hand uses 2.x C API which is
not available in 3.x.  Namely, the PyInstance_NewRaw function.  In
order to fix the bug described in issue #5180, I had to emulate
PyInstance_NewRaw using type->tp_alloc.  I considered an rejected the
idea to use tp_new instead. [2]

Is this the right way to proceed?  The patch is attached to the issue. [3]


[1] http://bugs.python.org/issue5180
[2] http://bugs.python.org/issue5180#msg108846
[3] http://bugs.python.org/file17792/issue5180.diff


More information about the Python-Dev mailing list