[issue14577] pickling uses __class__ so you can't pickle proxy/mock objects that pretend to be other objects
report at bugs.python.org
Sat Apr 14 13:16:54 CEST 2012
New submission from Michael Foord <michael at voidspace.org.uk>:
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
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).
title: pickling uses __class__ so you can't pickle proxy/mock objects that pretend to be other objects
Python tracker <report at bugs.python.org>
More information about the Python-bugs-list