A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://python.github.io/peps/pep-0663/ below:

PEP 663 – Standardizing Enum str(), repr(), and format() behaviors

PEP 663 – Standardizing Enum str(), repr(), and format() behaviors
Author:
Ethan Furman <ethan at stoneleaf.us>
Discussions-To:
Python-Dev list
Status:
Rejected
Type:
Informational
Created:
30-Jun-2021
Python-Version:
3.11
Post-History:
20-Jul-2021, 02-Nov-2021
Resolution:
Python-Dev message
Table of Contents Abstract

Update the repr(), str(), and format() of the various Enum types to better match their intended purpose. For example, IntEnum will have its str() change to match its format(), while a user-mixed int-enum will have its format() match its str(). In all cases, an enum’s str() and format() will be the same (unless the user overrides format()).

Add a global enum decorator which changes the str() and repr() (and format()) of the decorated enum to be a valid global reference: i.e. re.IGNORECASE instead of <RegexFlag.IGNORECASE: 2>.

Motivation

Having the str() of IntEnum and IntFlag not be the value causes bugs and extra work when replacing existing constants.

Having the str() and format() of an enum member be different can be confusing.

The addition of StrEnum with its requirement to have its str() be its value is inconsistent with other provided Enum’s str.

The iteration of Flag members, which directly affects their repr(), is inelegant at best, and buggy at worst.

Rationale

Enums are becoming more common in the standard library; being able to recognize enum members by their repr(), and having that repr() be easy to parse, is useful and can save time and effort in understanding and debugging code.

However, the enums with mixed-in data types (IntEnum, IntFlag, and the new StrEnum) need to be more backwards compatible with the constants they are replacing – specifically, str(replacement_enum_member) == str(original_constant) should be true (and the same for format()).

IntEnum, IntFlag, and StrEnum should be as close to a drop-in replacement of existing integer and string constants as is possible. Towards that goal, the str() output of each should be its inherent value; e.g. if Color is an IntEnum:

>>> Color.RED
<Color.RED: 1>
>>> str(Color.RED)
'1'
>>> format(Color.RED)
'1'

Note that format() already produces the correct output, only str() needs updating.

As much as possible, the str(), repr(), and format() of enum members should be standardized across the standard library. However, up to Python 3.10 several enums in the standard library have a custom str() and/or repr().

The repr() of Flag currently includes aliases, which it should not; fixing that will, of course, already change its repr() in certain cases.

Specification

There are three broad categories of enum usage:

There are also two styles:

Some sample enums:

# module: tools.py

class Hue(Enum):  # or IntEnum
    LIGHT = -1
    NORMAL = 0
    DARK = +1

class Color(Flag):  # or IntFlag
    RED = 1
    GREEN = 2
    BLUE = 4

class Grey(int, Enum):  # or (int, Flag)
   BLACK = 0
   WHITE = 1

Using the above enumerations, the following two tables show the old and new output (blank cells indicate no change):

style category enum repr() enum str() enum format() normal simple 3.10 new user mixed 3.10 1 new Grey.WHITE int drop-in 3.10 Hue.LIGHT new -1 global simple 3.10 <Hue.LIGHT: -1> Hue.LIGHT Hue.LIGHT new tools.LIGHT LIGHT LIGHT user mixed 3.10 <Grey.WHITE: 1 Grey.WHITE Grey.WHITE new tools.WHITE WHITE WHITE int drop-in 3.10 <Hue.LIGHT: -1> Hue.LIGHT new tools.LIGHT -1 style category flag repr() flag str() flag format() normal simple 3.10 <Color.RED|GREEN: 3> Color.RED|GREEN Color.RED|GREEN new <Color(3): RED|GREEN> Color.RED|Color.GREEN Color.RED|Color.GREEN user mixed 3.10 <Grey.WHITE: 1> 1 new <Grey(1): WHITE> Grey.WHITE int drop-in 3.10 <Color.RED|GREEN: 3> Color.RED|GREEN new <Color(3): RED|GREEN> 3 global simple 3.10 <Color.RED|GREEN: 3> Color.RED|GREEN Color.RED|GREEN new tools.RED|tools.GREEN RED|GREEN RED|GREEN user mixed 3.10 <Grey.WHITE: 1> Grey.WHITE 1 new tools.WHITE WHITE WHITE int drop-in 3.10 <Color.RED|GREEN: 3> Color.RED|GREEN new tools.RED|tools.GREEN 3

These two tables show the final result:

style category enum repr() enum str() enum format() normal simple <Hue.LIGHT: -1> Hue.LIGHT Hue.LIGHT user mixed <Grey.WHITE: 1> Grey.WHITE Grey.WHITE int drop-in <Hue.LIGHT: -1> -1 -1 global simple tools.LIGHT LIGHT LIGHT user mixed tools.WHITE WHITE WHITE int drop-in tools.LIGHT -1 -1 style category flag repr() flag str() flag format() normal simple <Color(3): RED|GREEN> Color.RED|Color.GREEN Color.RED|Color.GREEN user mixed <Grey(1): WHITE> Grey.WHITE Grey.WHITE int drop-in <Color(3): RED|GREEN> 3 3 global simple tools.RED|tools.GREEN RED|GREEN RED|GREEN user mixed tools.WHITE WHITE WHITE int drop-in tools.RED|tools.GREEN 3 3

As can be seen, repr() is primarily affected by whether the members are global, while str() is affected by being global or by being a drop-in replacement, with the drop-in replacement status having a higher priority. Also, the basic repr() and str() have changed for flags as the old style was flawed.

Backwards Compatibility

Backwards 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.

Normal usage of enum members will not change: re.ASCII can still be used as re.ASCII and will still compare equal to 256.

If the previous output needs to be maintained, for example to ensure compatibility between different Python versions, software projects will need to create their own enum base class with the appropriate methods overridden.

Note that by changing the str() of the drop-in category, we will actually prevent future breakage when IntEnum, et al, are used to replace existing constants.

Copyright

This document is placed in the public domain or under the CC0-1.0-Universal license, whichever is more permissive.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4