This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author michael.foord
Recipients michael.foord
Date 2012-04-14.11:16:53
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1334402214.26.0.28776275463.issue14577@psf.upfronthosting.co.za>
In-reply-to
Content
Pickling uses __class__ instead of type(obj) to determine the type to pickle. This means that objects which pretend to be other objects (like proxy and mock objects) can't be pickled correctly:

>>> class Foo(object):
...  __class__ = property(lambda *a, **k: int)
...  
... 
>>> from pickle import dumps
>>> dumps(Foo())
b'\x80\x03cbuiltins\nint\nq\x00)\x81q\x01}q\x02b.'

Here Foo() is pickled as an int. In Python 2 using type(obj) wouldn't work for old style classes, but I don't see a reason not to use type(obj) in Python 3.

Note that also, the pickle protocol methods like __getstate__ etc are looked up on the object instance (using getattr) rather than on the object type. This means that __getattr__ is invoked to look them up - requiring special casing in objects that provide __getattr__ to avoid them (raise  an AttributeError if they don't provide these methods). This affects three object types in the unittest.mock namespace (_Call, sentinel and the Mock variants).
History
Date User Action Args
2012-04-14 11:16:54michael.foordsetrecipients: + michael.foord
2012-04-14 11:16:54michael.foordsetmessageid: <1334402214.26.0.28776275463.issue14577@psf.upfronthosting.co.za>
2012-04-14 11:16:53michael.foordlinkissue14577 messages
2012-04-14 11:16:53michael.foordcreate