El lun, 28 jun 2021 a las 1:00, Ethan Furman (<ethan@stoneleaf.us>) escribió:
I have spoken with Pablo (3.10 RM), and he agrees that a change to Enum str() in 3.10 and another in 3.11 is less than
ideal, so this new thread is to collect comments about Enum and it's str() and repr() and whether the changes take
effect in 3.10, 3.11, or both.

TL;DR -- sorry, there isn't one.

History:
--------
As Enum and IntEnum have started proliferating in the stdlib, some of those enumerations have changed the str() and
repr() of their members -- for example, in 3.8 re.RegexFlag had its repr() and str() changed to be module.name
(re.ASCII) for both instead of <enum_class.name: value> (<RegexFlag.ASCII: 256>) for the repr(); that change made sense
because all the members are exported to re's global name space, and they are accessed as `re.ASCII` in existing code.

While a good change (in my opinion and with which I had nothing to do), we now have stdlib enumerations with differing
str() and repr()s, which is a minor ding against recognizability and usability.


Current 3.10 Changes
--------------------
In an effort to standardize the stdlib enums, a new decorator was added: global_enum().  It can be called manually (for
example in re.RegexFlag), or automatically by Enum._convert_ (for example in ssl.VerifyFlags).

That changed was visually appealing, and I had users wanting that type of output for Enum in general, so after asking
for feedback on python-dev and python-ideas (and receiving little) I changed the basic str() and repr() of Enum to:

- str(): NAME
- repr(): enum.NAME

While working on some other bugs/changes in Enum.__format__ and serialization in general, I have come to believe that
IntEnum (and IntFlag) should be as near-perfect a drop-in replacement as possible for when they are used to replace
existing integer constants (which I believe is their most important use-case).


Reverting 3.10 Changes
----------------------
I have been increasingly unhappy with the general `Enum.__repr__` change, so while the stdlib global repr() change is
staying, Enum, IntEnum, etc., is going back to <enum_class.NAME: value>.
Great! 


Proposed 3.10 Change (for 3.10.0 beta 4)
----------------------------------------
In order to improve the drop-in replacement use-case for IntEnum and IntFlag, I would like to change the str() for those
two to be simply the value of the member, as if it was still a plain integer and not part of an enumeration.  At that
point the only obvious difference would be the repr(), which I think is the most important and useful change as that is
what (should) show up in log files, the REPL, etc.

This would also make IntEnum and IntFlag consistent with StrEnum as, for other reasons, StrEnum member str()s are the
values of the members rather than the names of the members.  Note also that this change would not affect user created
enumerations that mixed in int on their own.


The Question
------------
With all the changes currently happening to the str()s and repr()s of the various enums, what are the good reasons to
not make this final change now, and instead have one more change in 3.11?

Just to make myself less confused, the behavior of str(Color.RED) (where Color is an IntEnum) is:
- 3.9 and below: "Color.RED"
- Current 3.10 branch: "RED"
- Proposed change: "256"

I agree that we shouldn't change the behavior in 3.10 and again in 3.11, and also that the proposed behavior is the best long-term option.

If it's too late for completely new behavior in 3.10, we could instead revert 3.10 to use the 3.9 behavior and make the change only in 3.11. 
 


--
~Ethan~


Summary of Enum str()s and repr()s by category

|               | repr()         | str()     | format()
Somewhat unrelatedly, I don't like that str() and format() may return different results for enums; I think enums are the only type I commonly encounter for which this is the case. If possible, any change we make should move us closer to having both return the same result.
 
| stdlib global | re.ASCII       | re.ASCII  | 256
| Enum          | <Color.RED: 1> | Color.RED | RED
| IntEnum       | <Color.RED: 1> | 1         | 1
| int, Enum     | <Color.RED: 1> | Color.RED | 1 (will be RED in 3.12 due to back-compatibility
|               |                |             constraints which should affect very few people as
|               |                |             as they are probably using IntEnum instead of mixing
|               |                |             in int themselves -- comments about this likelihood also
|               |                |             appreciated)
It does happen sometimes: https://grep.app/search?q=%28int%2C%20Enum%29&case=true&filter[lang][0]=Python .  
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-leave@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/ZMC67QA2JVQJSWSFWRS6IM6ZX4EK277G/
Code of Conduct: http://python.org/psf/codeofconduct/