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

Eli Bendersky eliben at gmail.com
Sat Apr 13 14:43:32 CEST 2013


On Sat, Apr 13, 2013 at 1:31 AM, Serhiy Storchaka <storchaka at gmail.com>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. Right. Fixed (removed this part because it's redundant), thanks.

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? And same question for the enumeration's str(). 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? I've updated the PEP since then. It also shows how to use getitem syntax to access by value.

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"). Enumeration values ------------------ 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 agree, but not sure how to resolve it. I hope it's clear enough from the context.

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"). See long discussion previously in this thread.

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? Yes. IntEnumValue (the value class underlying IntEnum) subclasses int.

Enumerations created with the class syntax can also be pickled and unpickled::

This does not apply to marshalling, I suppose? Perhaps this is worth to mention explicitly. There may be some errors of incompatibility.

No special provision has been made for marshalling.

The Enum class is callable, providing the following convenience API::

>>> Animals = Enum('Animals', 'ant bee cat dog') >>> Animals <Animals {ant: 1, bee: 2, cat: 3, dog: 4}> >>> Animals.ant <EnumValue: Animals.ant [value=1]> >>> Animals.ant.value 1 The semantics of this API resemble namedtuple. The first argument of the call to Enum is the name of the enumeration. The second argument is a source of enumeration value names. It can be a whitespace-separated string of names, a sequence of names or a sequence of 2-tuples with key/value pairs.

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.

I don't know if there was a special reason for this. Perhaps backwards compatibility with existing flufl.enum APIs. Barry may know more about this.

Use-cases in the standard library =================================

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?

It is applicable, in the sense that os.O_CREAT etc can be IntEnum values. Their bitset operation results will be simple integers. It's not planned to add a special enum for this - this was ruled against during the Pycon discussions.

Eli -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.python.org/pipermail/python-dev/attachments/20130413/8ba7b9d0/attachment.html>



More information about the Python-Dev mailing list