[Python-Dev] cherry pick a change to Enum

Ethan Furman ethan at stoneleaf.us
Fri Feb 21 09:36:09 CET 2014

Greetings, all!

Larry asked me to bring this to PyDev, so here it is.

The issues involved are:

http://bugs.python.org/issue20534  -> already in RC1
http://bugs.python.org/issue20653  -> hoping to get cherry-picked

When I put Enum together, my knowledge of pickle and its protocols was dreadfully weak.  As a result, I didn't make the 
best choice in implementing it [1].

Just before RC1 was cut, Serhiy discovered a problem with pickling Enums at protocol four, and with his help I fixed 
that (this is the part that is already in RC1).  This fix consisted primarily of adding a __reduce_ex__ to the Enum 
class, and also checking for all the pickle protocols in a mixed-in type [2], but I left __getnewargs__ in.  Not only 
that, and worse, I wasn't checking to see if the new subclass had its own __getnewargs__ or __reduce_ex__ before I 
invalidated the class for pickling [3].  This means that even though a subclass could have its own __reduce_ex__ to make 
pickling/unpickling possible, it will be ignored.

All the previous changes to disallow something have been for strategic reasons (the usual ones being either consistency, 
or "it doesn't make sense for an enum member/class to behave that way"), but this is effectively disallowing a user to 
specify how their enums should be pickled, and I am unaware of any reason why this should be.


Is there a valid reason to not allow a user to modify how their enums are pickled?

If not, should we put the change in RC2 / Final?  The main reason I'm pushing for this is that Enum is still new, but 
after 3.4.0 is cut we then have to deal with backwards compatibility issues.

Thanks for your time and thoughts.


[1] I chose __getnewargs__, with the result that originally Enum didn't support pickle protocols 0 or 1, and when 4 was 
added later it had trouble with some types of Enum subclasses (tuples, to be exact).

[2] Those protocol methods being __reduce__, __reduce_ex__, __getnewargs__, and __getnewargs_ex__.

[3] This logic error has been there from the beginning, it did not sneak in in the last patch before RC1.

More information about the Python-Dev mailing list