[issue20534] Enum tests fail with pickle protocol 4

Serhiy Storchaka report at bugs.python.org
Sat Feb 8 08:11:43 CET 2014


Serhiy Storchaka added the comment:

> -------------------------------------------------------------------------
> The object class implements both __reduce__() and __reduce_ex__();
> however, if a subclass overrides __reduce__() but not __reduce_ex__(),
> the __reduce_ex__() implementation detects this and calls __reduce__().
> -------------------------------------------------------------------------

This is about default  object.__reduce_ex__() implementation. But base class 
can override it.

>>> import enum, pickle
>>> class C(int):
...     def __reduce_ex__(self, proto):
...         return C, (int(self),)
... 
>>> class E(C):
...     X = C(42)
... 
>>> y = C(42)
>>> pickle.loads(pickle.dumps(y))
42
>>> type(pickle.loads(pickle.dumps(y)))
<class '__main__.C'>
>>> pickle.loads(pickle.dumps(E.X))
42
>>> type(pickle.loads(pickle.dumps(E.X)))
<class '__main__.C'>

Well, the direct cause is that the Enum class in question failed to define 
__getnewargs__; the indirect cause is that without __getnewargs__ the 
metaclass will call _make_class_unpicklable.

> Well, the direct cause is that the Enum class in question failed to define
> __getnewargs__; the indirect cause is that without __getnewargs__ the
> metaclass will call _make_class_unpicklable.
> 
> So neither the enum nor its members should pickle.

Actually they don't pickle due to wrong __module__. After adding

    NEI.__module__ = NamedInt.__module__ = __name__

PicklingError no longer raised for enum class.

And "BadPickle.__qualname__ = 'BadPickle'" in test_exploding_pickle is 
redundant, because BadPickle.__qualname__ already is 'BadPickle' (due to the 
module argument in constructor).

----------

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue20534>
_______________________________________


More information about the Python-bugs-list mailing list