[Python-Dev] PEP 435 -- Adding an Enum type to the Python standard library (original) (raw)

Barry Warsaw barry at python.org
Sat Apr 20 21🔞08 CEST 2013


On Apr 13, 2013, at 11:31 AM, Serhiy Storchaka wrote:

On 12.04.13 15:55, Eli Bendersky wrote:

The enumeration value names are available through the class members::

>>> for member in Colors.members: ... print(member) red green blue This is unnecessary because enumerations are iterable. Colors.members is equal to [v.name for v in Colors] and the latter looks more preferable, because it does not use the magic method.

members was really a holdover from earlier versions. I've removed this, but I've added an dir().

The str and repr of the enumeration class also provides useful information::

>>> print(Colors) <Colors {red: 1, green: 2, blue: 3}> >>> print(repr(Colors)) <Colors {red: 1, green: 2, blue: 3}> Does the enumeration's repr() use str() or repr() for the enumeration values?

No, enumeration values have different reprs and strs.

And same question for the enumeration's str().

Enumerations share a repr and str (well, technically, Enums don't define a str()).

To programmatically access enumeration values, use getattr::

>>> getattr(Colors, 'red') <EnumValue: Colors.red [value=1]> How to get the enumeration value by its value?

Use getitem syntax:

>>> from flufl.enum import Enum
>>> A = Enum('A', 'a b c')
>>> A[2]
<EnumValue: A.b [value=2]>

Ordered comparisons between enumeration values are not supported. Enums are not integers (but see IntEnum below):: It's unexpected if values of the enumeration values have the natural order. And values of the enumeration values should be comparable ("Iteration is defined as the sorted order of the item values").

This is one reason why Enums are not comparable except by equality. While I think it's not a good idea to mix the types of Enum item values, it is possible, and I don't think we should add strict checks to enforce this for the base Enum. Thus we cannot guarantee that <, >, <=, or >= will not throw a TypeError.

IntEnums do define these because they can be guaranteed to succeed, since their enumeration item values are guaranteed to be integers.

There is some ambiguity in the term "enumeration values". On the one hand, it's the singleton instances of the enumeration class (Colors.red, Colors.gree, Colors.blue), and on the other hand it is their values (1, 2, 3).

I've just made sure that the flufl.enum using.rst document is consistent here. The terms I'm using are "enumeration item" to define things like Colors.red and "enumeration item value" (or sometimes just "enumeration value") to define the value of the enumeration item, e.g. 2, and it's available on the .value attribute of the item. "Enumeration item name" is essentially the attribute name, and is available on the .name attribute of the item.

But if the value is important, enumerations can have arbitrary values. Should enumeration values be hashable? At least they should be comparable ("Iteration is defined as the sorted order of the item values").

Given my previous responses, these questions should be already answered.

IntEnum values behave like integers in other ways you'd expect::

>>> int(Shape.circle) 1 >>> ['a', 'b', 'c'][Shape.circle] 'b' >>> [i for i in range(Shape.square)] [0, 1] What is isinstance(Shape.circle, int)? Does PyLongCheck() return true for IntEnum values?

True. Yes, because IntEnumValues inherit from int.

Why the enumeration starts from 1? It is not consistent with namedtuple, in which indices are zero-based, and I believe that in most practical cases the enumeration integer values are zero-based.

There are several reasons:

The Python standard library has many places where named integer constants used as bitmasks (i.e. os.OCREAT | os.OWRONLY | os.OTRUNC, select.POLLIN | select.POLLPRI, re.IGNORECASE | re.ASCII). The proposed PEP is not applicable to these cases. Whether it is planned expansion of Enum or additional EnumSet class to aid in these cases?

IntEnums work fine for these cases, but it's true that the result of a logical operation is an int and not a subclass with a nice repr. Contributions are welcome.

-Barry



More information about the Python-Dev mailing list