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

Alexander Belopolsky alexander.belopolsky at gmail.com
Thu Jul 15 01:24:28 CEST 2010


I am reposting the same question again because it seems to have gone
unnoticed.  Antoine Pitrou and I had a brief discussion on the
tracker, but did not reach an agreement on whether a more elaborate
code is needed to replace PyInstance_NewRaw than a simple
type->tp_alloc() call.

I have reviewed the patch again and I am convinced that this issue
comes into play only when 3.x loads 2.x pickles that contain instances
of classic classes.   (Specifically, this code is used to process INST
and OBJ pickle opcodes that are not produced by 3.x.)  This means that
Antoine's concern that "tomorrow [object_new()] may entail additional
operations" is not valid  - there is no tomorrow for 2.x. :-)  This
also means that the type cannot inherit from anything other than
object and thus cannot have funny tp_flags or tp_alloc that does not
create a usable object.

I would like to commit the patch as presented.  If a corner case is
discovered later where type->tp_alloc() is not sufficient, we can deal
with it then.

On Mon, Jun 28, 2010 at 3:59 PM, Alexander Belopolsky
<alexander.belopolsky at gmail.com> wrote:
> 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