enum — Support for enumerations

An enumeration is a set of symbolic names (members) bound to unique, constant values. Within an enumeration, the members can be compared by identity, and the enumeration itself can be iterated over.

1. Module Contents

This module defines four enumeration classes that can be used to define unique sets of names and values: Enum, IntEnum, Flag, and IntFlag. It also defines one decorator, unique(), and one helper, auto.

Base class for creating enumerated constants that are also subclasses of int.

class enum.IntFlag

Base class for creating enumerated constants that can be combined using the bitwise operators without losing their IntFlag membership. IntFlag members are also subclasses of int.

class enum.Flag

Base class for creating enumerated constants that can be combined using the bitwise operations without losing their Flag membership.

enum.unique()

Enum class decorator that ensures only one name is bound to any one value.

class enum.auto

Instances are replaced with an appropriate value for Enum members.

New in version 3.6: Flag, IntFlag, auto

2. Creating an Enum

Enumerations are created using the class syntax, which makes them easy to read and write. An alternative creation method is described in Functional API. To define an enumeration, subclass Enum as follows:

Member values can be anything: int, str, etc.. If the exact value is unimportant you may use auto instances and an appropriate value will be chosen for you. Care must be taken if you mix auto with other values.

Note

Nomenclature

The class Color is an enumeration (or enum)

The attributes Color.RED, Color.GREEN, etc., are enumeration members (or enum members) and are functionally constants.

The enum members have names and values (the name of Color.RED is RED, the value of Color.BLUE is 3, etc.)

3. Programmatic access to enumeration members and their attributes

Sometimes it’s useful to access members in enumerations programmatically (i.e. situations where Color.RED won’t do because the exact color is not known at program-writing time). Enum allows such access:

>>> Color(1)
<Color.RED: 1>
>>> Color(3)
<Color.BLUE: 3>

If you want to access enum members by name, use item access:

>>> Color['RED']
<Color.RED: 1>
>>> Color['GREEN']
<Color.GREEN: 2>

If you have an enum member and need its name or value:

>>> member = Color.RED
>>> member.name
'RED'
>>> member.value
1

4. Duplicating enum members and values

However, two enum members are allowed to have the same value. Given two members A and B with the same value (and A defined first), B is an alias to A. By-value lookup of the value of A and B will return A. By-name lookup of B will also return A:

Attempting to create a member with the same name as an already defined attribute (another member, a method, etc.) or attempting to create an attribute with the same name as a member is not allowed.

5. Ensuring unique enumeration values

By default, enumerations allow multiple names as aliases for the same value. When this behavior isn’t desired, the following decorator can be used to ensure each value is used only once in the enumeration:

@enum.unique

A class decorator specifically for enumerations. It searches an enumeration’s __members__ gathering any aliases it finds; if any are found ValueError is raised with the details:

Comparisons against non-enumeration values will always compare not equal (again, IntEnum was explicitly designed to behave differently, see below):

>>> Color.BLUE == 2
False

9. Allowed members and attributes of enumerations

The examples above use integers for enumeration values. Using integers is short and handy (and provided by default by the Functional API), but not strictly enforced. In the vast majority of use-cases, one doesn’t care what the actual value of an enumeration is. But if the value is important, enumerations can have arbitrary values.

Enumerations are Python classes, and can have methods and special methods as usual. If we have this enumeration:

The rules for what is allowed are as follows: names that start and end with a single underscore are reserved by enum and cannot be used; all other attributes defined within an enumeration will become members of this enumeration, with the exception of special methods (__str__(), __add__(), etc.) and descriptors (methods are also descriptors).

Note: if your enumeration defines __new__() and/or __init__() then whatever value(s) were given to the enum member will be passed into those methods. See Planet for an example.

10. Restricted subclassing of enumerations

Subclassing an enumeration is allowed only if the enumeration does not define any members. So this is forbidden:

Allowing subclassing of enums that define members would lead to a violation of some important invariants of types and instances. On the other hand, it makes sense to allow sharing some common behavior between a group of enumerations. (See OrderedEnum for an example.)

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 the source of enumeration member names. It can be a whitespace-separated string of names, a sequence of names, a sequence of 2-tuples with key/value pairs, or a mapping (e.g. dictionary) of names to values. The last two options enable assigning arbitrary values to enumerations; the others auto-assign increasing integers starting with 1 (use the start parameter to specify a different starting value). A new class derived from Enum is returned. In other words, the above assignment to Animal is equivalent to:

The reason for defaulting to 1 as the starting number and not 0 is that 0 is False in a boolean sense, but enum members all evaluate to True.

Pickling enums created with the functional API can be tricky as frame stack implementation details are used to try and figure out which module the enumeration is being created in (e.g. it will fail if you use a utility function in separate module, and also may not work on IronPython or Jython). The solution is to specify the module name explicitly as follows:

>>> Animal = Enum('Animal', 'ANT BEE CAT DOG', module=__name__)

Warning

If module is not supplied, and Enum cannot determine what it is, the new Enum members will not be unpicklable; to keep errors closer to the source, pickling will be disabled.

The new pickle protocol 4 also, in some circumstances, relies on __qualname__ being set to the location where pickle will be able to find the class. For example, if the class was made available in class SomeData in the global scope:

The Enum members. This can be a whitespace or comma separated string (values will start at 1 unless otherwise specified):

'RED GREEN BLUE' | 'RED,GREEN,BLUE' | 'RED, GREEN, BLUE'

or an iterator of names:

['RED', 'GREEN', 'BLUE']

or an iterator of (name, value) pairs:

[('CYAN', 4), ('MAGENTA', 5), ('YELLOW', 6)]

or a mapping:

{'CHARTREUSE': 7, 'SEA_GREEN': 11, 'ROSEMARY': 42}

module:

name of module where new Enum class can be found.

qualname:

where in module new Enum class can be found.

type:

type to mix in to new Enum class.

start:

number to start counting at if only names are passed in.

Changed in version 3.5: The start parameter was added.

13. Derived Enumerations

13.1. IntEnum

The first variation of Enum that is provided is also a subclass of int. Members of an IntEnum can be compared to integers; by extension, integer enumerations of different types can also be compared to each other:

13.2. IntFlag

The next variation of Enum provided, IntFlag, is also based on int. The difference being IntFlag members can be combined using the bitwise operators (&, |, ^, ~) and the result is still an IntFlag member. However, as the name implies, IntFlag members also subclass int and can be used wherever an int is used. Any operation on an IntFlag member besides the bit-wise operations will lose the IntFlag membership.

Another important difference between IntFlag and Enum is that if no flags are set (the value is 0), its boolean evaluation is False:

>>> Perm.R & Perm.X
<Perm.0: 0>
>>> bool(Perm.R & Perm.X)
False

Because IntFlag members are also subclasses of int they can be combined with them:

>>> Perm.X | 8
<Perm.8|X: 9>

13.3. Flag

The last variation is Flag. Like IntFlag, Flag members can be combined using the bitwise operators (&, |, ^, ~). Unlike IntFlag, they cannot be combined with, nor compared against, any other Flag enumeration, nor int. While it is possible to specify the values directly it is recommended to use auto as the value and let Flag select an appropriate value.

New in version 3.6.

Like IntFlag, if a combination of Flag members results in no flags being set, the boolean evaluation is False:

For the majority of new code, Enum and Flag are strongly recommended, since IntEnum and IntFlag break some semantic promises of an enumeration (by being comparable to integers, and thus by transitivity to other unrelated enumerations). IntEnum and IntFlag should be used only in cases where Enum and Flag will not do; for example, when integer constants are replaced with enumerations, or for interoperability with other systems.

13.4. Others

While IntEnum is part of the enum module, it would be very simple to implement independently:

class IntEnum(int, Enum):
pass

This demonstrates how similar derived enumerations can be defined; for example a StrEnum that mixes in str instead of int.

Some rules:

When subclassing Enum, mix-in types must appear before Enum itself in the sequence of bases, as in the IntEnum example above.

While Enum can have members of any type, once you mix in an additional type, all the members must have values of that type, e.g. int above. This restriction does not apply to mix-ins which only add methods and don’t specify another data type such as int or str.

When another data type is mixed in, the value attribute is not the same as the enum member itself, although it is equivalent and will compare equal.

%-style formatting: %s and %r call the Enum class’s __str__() and __repr__() respectively; other codes (such as %i or %h for IntEnum) treat the enum member as its mixed-in type.

14. Interesting examples

While Enum, IntEnum, IntFlag, and Flag are expected to cover the majority of use-cases, they cannot cover them all. Here are recipes for some different types of enumerations that can be used directly, or as examples for creating one’s own.

14.1. Omitting values

In many use-cases one doesn’t care what the actual value of an enumeration is. There are several ways to define this type of simple enumeration:

This is a useful example for subclassing Enum to add or change other behaviors as well as disallowing aliases. If the only desired change is disallowing aliases, the unique() decorator can be used instead.

14.4. Planet

If __new__() or __init__() is defined the value of the enum member will be passed to those methods:

15.2. Enum Members (aka instances)

The most interesting thing about Enum members is that they are singletons. EnumMeta creates them all while it is creating the Enum class itself, and then puts a custom __new__() in place to ensure that no new ones are ever instantiated by returning only the existing member instances.

15.3. Finer Points

15.3.1. Supported __dunder__ names

__members__ is an OrderedDict of member_name:member items. It is only available on the class.

__new__(), if specified, must create and return the enum members; it is also a very good idea to set the member’s _value_ appropriately. Once all the members are created it is no longer used.

15.3.2. Supported _sunder_ names

_name_ – name of the member

_value_ – value of the member; can be set / modified in __new__

_missing_ – a lookup function used when a value is not found; may be overridden

_order_ – used in Python 2/3 code to ensure member order is consistent (class attribute, removed during class creation)

_generate_next_value_ – used by the Functional API and by auto to get an appropriate value for an enum member; may be overridden

New in version 3.6: _missing_, _order_, _generate_next_value_

To help keep Python 2 / Python 3 code in sync an _order_ attribute can be provided. It will be checked against the actual order of the enumeration and raise an error if the two do not match:

In Python 2 code the _order_ attribute is necessary as definition order is lost before it can be recorded.

15.3.3. Enum member type

Enum members are instances of their Enum class, and are normally accessed as EnumClass.member. Under certain circumstances they can also be accessed as EnumClass.member.member, but you should never do this as that lookup may fail or, worse, return something besides the Enum member you are looking for (this is another good reason to use all-uppercase names for members):

15.3.4. Boolean value of Enum classes and members

Enum members that are mixed with non-Enum types (such as int, str, etc.) are evaluated according to the mixed-in type’s rules; otherwise, all members evaluate as True. To make your own Enum’s boolean evaluation depend on the member’s value add the following to your class: