The Steering Council has been discussing PEP 663 (Improving and Standardizing Enum str(), repr(), and format() behaviors), for the last few weeks. We want to thank you for your work on this PEP and your continued work on enums in the standard library.
Upon further consideration, we have decided to reject this PEP, although we do agree with the need to change IntEnum’s str() or format(); see below.
Several reasons are leading the SC to its conclusion. The first is that enums in the stdlib are already highly complex, and consistency is our top priority over time. Having predictable and stable strs and reprs across Python versions is more important than the consistency among the various enum and non-enum types that the PEP proposes. The PEP rightly states that “[b]ackwards compatibility of stringified objects is not guaranteed across major Python versions, and there will be backwards compatibility breaks where software uses the repr(), str(), and format() output of enums in tests, documentation, data structures, and/or code generation”. Yet, we don’t believe that this provides a blanket license to break such backward compatibility. In this particular case, we believe the rationale given in the PEP is not sufficient justification for breaking this compatibility. Indeed, we have already seen cases of users impacted in different ways by this change, which led us into our previous decision to require a PEP for the changes.
Second, we find the PEP’s distinction between global and normal enum values to be highly confusing. It makes predicting the results more difficult, since the results will differ for the same object depending on where the name it is bound to is defined, and how it is accessed. To us, this makes understanding what object you are looking at much less clear. There are also not enough precedents for objects that modify their string representation based on where the name is bound.
Lastly, we’re concerned that all of these changes taken together leave us with a much more complicated enum implementation that is harder to maintain and understand. This may also make it more difficult for other Python implementations that do not have the same flexibility as CPython to do the necessary computations to distinguish between global / normal enumerations.
We understand that the rejection of this PEP means that some use cases may be more difficult to implement for users who need them, but we think that for the average user of enums, the current behavior is more predictable and comprehensible. We also recognize that backing these changes out for 3.11 will be a non-trivial amount of work given the other changes to enum so far. We want to find a way to help make that work easier for you.
One aspect of the PEP we do agree with is the alignment of IntEnum’s str() and format(). It is confusing that they give different results, and that is worth the small compatibility breakage to fix. We are uncertain whether it’s better to change str to be more like format or vice versa. Our recommendation is to take this discussion to python-dev and see if consensus on this topic can be reached.
On a related note, the SC has considered and approves your request for the backward compatibility exemption in https://github.com/python/steering-council/issues/80
Respectfully, -Barry (on behalf of the Python Steering Council)