==========
Enum HOWTO
==========

.. _enum-basic-tutorial:

.. currentmodule:: enum

An :class:`Enum` is a set of symbolic names bound to unique values.  They are
similar to global variables, but they offer a more useful :func:`repr()`,
grouping, type-safety, and a few other features.

They are most useful when you have a variable that can take one of a limited
selection of values.  For example, the days of the week::

    >>> from enum import Enum
    >>> class Weekday(Enum):
    ...     MONDAY = 1
    ...     TUESDAY = 2
    ...     WEDNESDAY = 3
    ...     THURSDAY = 4
    ...     FRIDAY = 5
    ...     SATURDAY = 6
    ...     SUNDAY = 7

Or perhaps the RGB primary colors::

    >>> from enum import Enum
    >>> class Color(Enum):
    ...     RED = 1
    ...     GREEN = 2
    ...     BLUE = 3

As you can see, creating an :class:`Enum` is as simple as writing a class that
inherits from :class:`Enum` itself.

.. note:: Case of Enum Members

    Because Enums are used to represent constants, and to help avoid issues
    with name clashes between mixin-class methods/attributes and enum names,
    we strongly recommend using UPPER_CASE names for members, and will be using
    that style in our examples.

Depending on the nature of the enum a member's value may or may not be
important, but either way that value can be used to get the corresponding
member::

    >>> Weekday(3)
    <Weekday.WEDNESDAY: 3>

As you can see, the ``repr()`` of a member shows the enum name, the member name,
and the value.  The ``str()`` of a member shows only the enum name and member
name::

    >>> print(Weekday.THURSDAY)
    Weekday.THURSDAY

The *type* of an enumeration member is the enum it belongs to::

    >>> type(Weekday.MONDAY)
    <enum 'Weekday'>
    >>> isinstance(Weekday.FRIDAY, Weekday)
    True

Enum members have an attribute that contains just their :attr:`name`::

    >>> print(Weekday.TUESDAY.name)
    TUESDAY

Likewise, they have an attribute for their :attr:`value`::


    >>> Weekday.WEDNESDAY.value
    3

Unlike many languages that treat enumerations solely as name/value pairs,
Python Enums can have behavior added.  For example, :class:`datetime.date`
has two methods for returning the weekday: :meth:`weekday` and :meth:`isoweekday`.
The difference is that one of them counts from 0-6 and the other from 1-7.
Rather than keep track of that ourselves we can add a method to the :class:`Weekday`
enum to extract the day from the :class:`date` instance and return the matching
enum member::

        @classmethod
        def from_date(cls, date):
            return cls(date.isoweekday())

The complete :class:`Weekday` enum now looks like this::

    >>> class Weekday(Enum):
    ...     MONDAY = 1
    ...     TUESDAY = 2
    ...     WEDNESDAY = 3
    ...     THURSDAY = 4
    ...     FRIDAY = 5
    ...     SATURDAY = 6
    ...     SUNDAY = 7
    ...     #
    ...     @classmethod
    ...     def from_date(cls, date):
    ...         return cls(date.isoweekday())

Now we can find out what today is!  Observe::

    >>> from datetime import date
    >>> Weekday.from_date(date.today())     # doctest: +SKIP
    <Weekday.TUESDAY: 2>

Of course, if you're reading this on some other day, you'll see that day instead.

This :class:`Weekday` enum is great if our variable only needs one day, but
what if we need several?  Maybe we're writing a function to plot chores during
a week, and don't want to use a :class:`list` -- we could use a different type
of :class:`Enum`::

    >>> from enum import Flag
    >>> class Weekday(Flag):
    ...     MONDAY = 1
    ...     TUESDAY = 2
    ...     WEDNESDAY = 4
    ...     THURSDAY = 8
    ...     FRIDAY = 16
    ...     SATURDAY = 32
    ...     SUNDAY = 64

We've changed two things: we're inherited from :class:`Flag`, and the values are
all powers of 2.

Just like the original :class:`Weekday` enum above, we can have a single selection::

    >>> first_week_day = Weekday.MONDAY
    >>> first_week_day
    <Weekday.MONDAY: 1>

But :class:`Flag` also allows us to combine several members into a single
variable::

    >>> weekend = Weekday.SATURDAY | Weekday.SUNDAY
    >>> weekend
    <Weekday.SATURDAY|SUNDAY: 96>

You can even iterate over a :class:`Flag` variable::

    >>> for day in weekend:
    ...     print(day)
    Weekday.SATURDAY
    Weekday.SUNDAY

Okay, let's get some chores set up::

    >>> chores_for_ethan = {
    ...     'feed the cat': Weekday.MONDAY | Weekday.WEDNESDAY | Weekday.FRIDAY,
    ...     'do the dishes': Weekday.TUESDAY | Weekday.THURSDAY,
    ...     'answer SO questions': Weekday.SATURDAY,
    ...     }

And a function to display the chores for a given day::

    >>> def show_chores(chores, day):
    ...     for chore, days in chores.items():
    ...         if day in days:
    ...             print(chore)
    ...
    >>> show_chores(chores_for_ethan, Weekday.SATURDAY)
    answer SO questions

In cases where the actual values of the members do not matter, you can save
yourself some work and use :func:`auto()` for the values::

    >>> from enum import auto
    >>> class Weekday(Flag):
    ...     MONDAY = auto()
    ...     TUESDAY = auto()
    ...     WEDNESDAY = auto()
    ...     THURSDAY = auto()
    ...     FRIDAY = auto()
    ...     SATURDAY = auto()
    ...     SUNDAY = auto()
    ...     WEEKEND = SATURDAY | SUNDAY


.. _enum-advanced-tutorial:


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 :attr:`name` or :attr:`value`::

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


Duplicating enum members and values
-----------------------------------

Having two enum members with the same name is invalid::

    >>> class Shape(Enum):
    ...     SQUARE = 2
    ...     SQUARE = 3
    ...
    Traceback (most recent call last):
    ...
    TypeError: 'SQUARE' already defined as 2

However, an enum member can have other names associated with it.  Given two
entries ``A`` and ``B`` with the same value (and ``A`` defined first), ``B``
is an alias for the member ``A``.  By-value lookup of the value of ``A`` will
return the member ``A``.  By-name lookup of ``A`` will return the member ``A``.
By-name lookup of ``B`` will also return the member ``A``::

    >>> class Shape(Enum):
    ...     SQUARE = 2
    ...     DIAMOND = 1
    ...     CIRCLE = 3
    ...     ALIAS_FOR_SQUARE = 2
    ...
    >>> Shape.SQUARE
    <Shape.SQUARE: 2>
    >>> Shape.ALIAS_FOR_SQUARE
    <Shape.SQUARE: 2>
    >>> Shape(2)
    <Shape.SQUARE: 2>

.. note::

    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.


Ensuring unique enumeration values
----------------------------------

By default, enumerations allow multiple names as aliases for the same value.
When this behavior isn't desired, you can use the :func:`unique` decorator::

    >>> from enum import Enum, unique
    >>> @unique
    ... class Mistake(Enum):
    ...     ONE = 1
    ...     TWO = 2
    ...     THREE = 3
    ...     FOUR = 3
    ...
    Traceback (most recent call last):
    ...
    ValueError: duplicate values found in <enum 'Mistake'>: FOUR -> THREE


Using automatic values
----------------------

If the exact value is unimportant you can use :class:`auto`::

    >>> from enum import Enum, auto
    >>> class Color(Enum):
    ...     RED = auto()
    ...     BLUE = auto()
    ...     GREEN = auto()
    ...
    >>> [member.value for member in Color]
    [1, 2, 3]

The values are chosen by :func:`_generate_next_value_`, which can be
overridden::

    >>> class AutoName(Enum):
    ...     @staticmethod
    ...     def _generate_next_value_(name, start, count, last_values):
    ...         return name
    ...
    >>> class Ordinal(AutoName):
    ...     NORTH = auto()
    ...     SOUTH = auto()
    ...     EAST = auto()
    ...     WEST = auto()
    ...
    >>> [member.value for member in Ordinal]
    ['NORTH', 'SOUTH', 'EAST', 'WEST']

.. note::

    The :meth:`_generate_next_value_` method must be defined before any members.

Iteration
---------

Iterating over the members of an enum does not provide the aliases::

    >>> list(Shape)
    [<Shape.SQUARE: 2>, <Shape.DIAMOND: 1>, <Shape.CIRCLE: 3>]
    >>> list(Weekday)
    [<Weekday.MONDAY: 1>, <Weekday.TUESDAY: 2>, <Weekday.WEDNESDAY: 4>, <Weekday.THURSDAY: 8>, <Weekday.FRIDAY: 16>, <Weekday.SATURDAY: 32>, <Weekday.SUNDAY: 64>]

Note that the aliases ``Shape.ALIAS_FOR_SQUARE`` and ``Weekday.WEEKEND`` aren't shown.

The special attribute ``__members__`` is a read-only ordered mapping of names
to members.  It includes all names defined in the enumeration, including the
aliases::

    >>> for name, member in Shape.__members__.items():
    ...     name, member
    ...
    ('SQUARE', <Shape.SQUARE: 2>)
    ('DIAMOND', <Shape.DIAMOND: 1>)
    ('CIRCLE', <Shape.CIRCLE: 3>)
    ('ALIAS_FOR_SQUARE', <Shape.SQUARE: 2>)

The ``__members__`` attribute can be used for detailed programmatic access to
the enumeration members.  For example, finding all the aliases::

    >>> [name for name, member in Shape.__members__.items() if member.name != name]
    ['ALIAS_FOR_SQUARE']

.. note::

   Aliases for flags include values with multiple flags set, such as ``3``,
   and no flags set, i.e. ``0``.


Comparisons
-----------

Enumeration members are compared by identity::

    >>> Color.RED is Color.RED
    True
    >>> Color.RED is Color.BLUE
    False
    >>> Color.RED is not Color.BLUE
    True

Ordered comparisons between enumeration values are *not* supported.  Enum
members are not integers (but see `IntEnum`_ below)::

    >>> Color.RED < Color.BLUE
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: '<' not supported between instances of 'Color' and 'Color'

Equality comparisons are defined though::

    >>> Color.BLUE == Color.RED
    False
    >>> Color.BLUE != Color.RED
    True
    >>> Color.BLUE == Color.BLUE
    True

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

    >>> Color.BLUE == 2
    False

.. warning::

   It is possible to reload modules -- if a reloaded module contains
   enums, they will be recreated, and the new members may not
   compare identical/equal to the original members.

Allowed members and attributes of enumerations
----------------------------------------------

Most of 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::

    >>> class Mood(Enum):
    ...     FUNKY = 1
    ...     HAPPY = 3
    ...
    ...     def describe(self):
    ...         # self is the member here
    ...         return self.name, self.value
    ...
    ...     def __str__(self):
    ...         return 'my custom str! {0}'.format(self.value)
    ...
    ...     @classmethod
    ...     def favorite_mood(cls):
    ...         # cls here is the enumeration
    ...         return cls.HAPPY
    ...

Then::

    >>> Mood.favorite_mood()
    <Mood.HAPPY: 3>
    >>> Mood.HAPPY.describe()
    ('HAPPY', 3)
    >>> str(Mood.FUNKY)
    'my custom str! 1'

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 (:meth:`__str__`,
:meth:`__add__`, etc.), descriptors (methods are also descriptors), and
variable names listed in :attr:`_ignore_`.

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

.. note::

    The :meth:`__new__` method, if defined, is used during creation of the Enum
    members; it is then replaced by Enum's :meth:`__new__` which is used after
    class creation for lookup of existing members.  See :ref:`new-vs-init` for
    more details.


Restricted Enum subclassing
---------------------------

A new :class:`Enum` class must have one base enum class, up to one concrete
data type, and as many :class:`object`-based mixin classes as needed.  The
order of these base classes is::

    class EnumName([mix-in, ...,] [data-type,] base-enum):
        pass

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

    >>> class MoreColor(Color):
    ...     PINK = 17
    ...
    Traceback (most recent call last):
    ...
    TypeError: <enum 'MoreColor'> cannot extend <enum 'Color'>

But this is allowed::

    >>> class Foo(Enum):
    ...     def some_behavior(self):
    ...         pass
    ...
    >>> class Bar(Foo):
    ...     HAPPY = 1
    ...     SAD = 2
    ...

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


.. _enum-dataclass-support:

Dataclass support
-----------------

When inheriting from a :class:`~dataclasses.dataclass`,
the :meth:`~Enum.__repr__` omits the inherited class' name.  For example::

    >>> from dataclasses import dataclass, field
    >>> @dataclass
    ... class CreatureDataMixin:
    ...     size: str
    ...     legs: int
    ...     tail: bool = field(repr=False, default=True)
    ...
    >>> class Creature(CreatureDataMixin, Enum):
    ...     BEETLE = 'small', 6
    ...     DOG = 'medium', 4
    ...
    >>> Creature.DOG
    <Creature.DOG: size='medium', legs=4>

Use the :func:`~dataclasses.dataclass` argument ``repr=False``
to use the standard :func:`repr`.

.. versionchanged:: 3.12
   Only the dataclass fields are shown in the value area, not the dataclass'
   name.

.. note::

   Adding :func:`~dataclasses.dataclass` decorator to :class:`Enum`
   and its subclasses is not supported. It will not raise any errors,
   but it will produce very strange results at runtime, such as members
   being equal to each other::

      >>> @dataclass               # don't do this: it does not make any sense
      ... class Color(Enum):
      ...    RED = 1
      ...    BLUE = 2
      ...
      >>> Color.RED is Color.BLUE
      False
      >>> Color.RED == Color.BLUE  # problem is here: they should not be equal
      True


Pickling
--------

Enumerations can be pickled and unpickled::

    >>> from test.test_enum import Fruit
    >>> from pickle import dumps, loads
    >>> Fruit.TOMATO is loads(dumps(Fruit.TOMATO))
    True

The usual restrictions for pickling apply: picklable enums must be defined in
the top level of a module, since unpickling requires them to be importable
from that module.

.. note::

    With pickle protocol version 4 it is possible to easily pickle enums
    nested in other classes.

It is possible to modify how enum members are pickled/unpickled by defining
:meth:`__reduce_ex__` in the enumeration class.  The default method is by-value,
but enums with complicated values may want to use by-name::

    >>> import enum
    >>> class MyEnum(enum.Enum):
    ...     __reduce_ex__ = enum.pickle_by_enum_name

.. note::

    Using by-name for flags is not recommended, as unnamed aliases will
    not unpickle.


Functional API
--------------

The :class:`Enum` class is callable, providing the following functional API::

    >>> Animal = Enum('Animal', 'ANT BEE CAT DOG')
    >>> Animal
    <enum 'Animal'>
    >>> Animal.ANT
    <Animal.ANT: 1>
    >>> list(Animal)
    [<Animal.ANT: 1>, <Animal.BEE: 2>, <Animal.CAT: 3>, <Animal.DOG: 4>]

The semantics of this API resemble :class:`~collections.namedtuple`. The first
argument of the call to :class:`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 :class:`Enum` is returned.  In other words, the above
assignment to :class:`Animal` is equivalent to::

    >>> class Animal(Enum):
    ...     ANT = 1
    ...     BEE = 2
    ...     CAT = 3
    ...     DOG = 4
    ...

The reason for defaulting to ``1`` as the starting number and not ``0`` is
that ``0`` is ``False`` in a boolean sense, but by default 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 a 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
:attr:`~definition.__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::

    >>> Animal = Enum('Animal', 'ANT BEE CAT DOG', qualname='SomeData.Animal')

The complete signature is::

    Enum(
        value='NewEnumName',
        names=<...>,
        *,
        module='...',
        qualname='...',
        type=<mixed-in class>,
        start=1,
        )

* *value*: What the new enum class will record as its name.

* *names*: 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.

.. versionchanged:: 3.5
   The *start* parameter was added.


Derived Enumerations
--------------------

IntEnum
^^^^^^^

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

    >>> from enum import IntEnum
    >>> class Shape(IntEnum):
    ...     CIRCLE = 1
    ...     SQUARE = 2
    ...
    >>> class Request(IntEnum):
    ...     POST = 1
    ...     GET = 2
    ...
    >>> Shape == 1
    False
    >>> Shape.CIRCLE == 1
    True
    >>> Shape.CIRCLE == Request.POST
    True

However, they still can't be compared to standard :class:`Enum` enumerations::

    >>> class Shape(IntEnum):
    ...     CIRCLE = 1
    ...     SQUARE = 2
    ...
    >>> class Color(Enum):
    ...     RED = 1
    ...     GREEN = 2
    ...
    >>> Shape.CIRCLE == Color.RED
    False

:class:`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]


StrEnum
^^^^^^^

The second variation of :class:`Enum` that is provided is also a subclass of
:class:`str`.  Members of a :class:`StrEnum` can be compared to strings;
by extension, string enumerations of different types can also be compared
to each other.

.. versionadded:: 3.11


IntFlag
^^^^^^^

The next variation of :class:`Enum` provided, :class:`IntFlag`, is also based
on :class:`int`.  The difference being :class:`IntFlag` members can be combined
using the bitwise operators (&, \|, ^, ~) and the result is still an
:class:`IntFlag` member, if possible.  Like :class:`IntEnum`, :class:`IntFlag`
members are also integers and can be used wherever an :class:`int` is used.

.. note::

    Any operation on an :class:`IntFlag` member besides the bit-wise operations will
    lose the :class:`IntFlag` membership.

    Bit-wise operations that result in invalid :class:`IntFlag` values will lose the
    :class:`IntFlag` membership.  See :class:`FlagBoundary` for
    details.

.. versionadded:: 3.6
.. versionchanged:: 3.11

Sample :class:`IntFlag` class::

    >>> from enum import IntFlag
    >>> class Perm(IntFlag):
    ...     R = 4
    ...     W = 2
    ...     X = 1
    ...
    >>> Perm.R | Perm.W
    <Perm.R|W: 6>
    >>> Perm.R + Perm.W
    6
    >>> RW = Perm.R | Perm.W
    >>> Perm.R in RW
    True

It is also possible to name the combinations::

    >>> class Perm(IntFlag):
    ...     R = 4
    ...     W = 2
    ...     X = 1
    ...     RWX = 7
    ...
    >>> Perm.RWX
    <Perm.RWX: 7>
    >>> ~Perm.RWX
    <Perm: 0>
    >>> Perm(7)
    <Perm.RWX: 7>

.. note::

    Named combinations are considered aliases.  Aliases do not show up during
    iteration, but can be returned from by-value lookups.

.. versionchanged:: 3.11

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

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

Because :class:`IntFlag` members are also subclasses of :class:`int` they can
be combined with them (but may lose :class:`IntFlag` membership::

    >>> Perm.X | 4
    <Perm.R|X: 5>

    >>> Perm.X + 8
    9

.. note::

    The negation operator, ``~``, always returns an :class:`IntFlag` member with a
    positive value::

        >>> (~Perm.X).value == (Perm.R|Perm.W).value == 6
        True

:class:`IntFlag` members can also be iterated over::

    >>> list(RW)
    [<Perm.R: 4>, <Perm.W: 2>]

.. versionadded:: 3.11


Flag
^^^^

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

.. versionadded:: 3.6

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

    >>> from enum import Flag, auto
    >>> class Color(Flag):
    ...     RED = auto()
    ...     BLUE = auto()
    ...     GREEN = auto()
    ...
    >>> Color.RED & Color.GREEN
    <Color: 0>
    >>> bool(Color.RED & Color.GREEN)
    False

Individual flags should have values that are powers of two (1, 2, 4, 8, ...),
while combinations of flags will not::

    >>> class Color(Flag):
    ...     RED = auto()
    ...     BLUE = auto()
    ...     GREEN = auto()
    ...     WHITE = RED | BLUE | GREEN
    ...
    >>> Color.WHITE
    <Color.WHITE: 7>

Giving a name to the "no flags set" condition does not change its boolean
value::

    >>> class Color(Flag):
    ...     BLACK = 0
    ...     RED = auto()
    ...     BLUE = auto()
    ...     GREEN = auto()
    ...
    >>> Color.BLACK
    <Color.BLACK: 0>
    >>> bool(Color.BLACK)
    False

:class:`Flag` members can also be iterated over::

    >>> purple = Color.RED | Color.BLUE
    >>> list(purple)
    [<Color.RED: 1>, <Color.BLUE: 2>]

.. versionadded:: 3.11

.. note::

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


Others
^^^^^^

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

    class IntEnum(int, ReprEnum):   # or Enum instead of ReprEnum
        pass

This demonstrates how similar derived enumerations can be defined; for example
a :class:`FloatEnum` that mixes in :class:`float` instead of :class:`int`.

Some rules:

1. When subclassing :class:`Enum`, mix-in types must appear before the
   :class:`Enum` class itself in the sequence of bases, as in the :class:`IntEnum`
   example above.
2. Mix-in types must be subclassable. For example, :class:`bool` and
   :class:`range` are not subclassable and will throw an error during Enum
   creation if used as the mix-in type.
3. While :class:`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.
   :class:`int` above.  This restriction does not apply to mix-ins which only
   add methods and don't specify another type.
4. When another data type is mixed in, the :attr:`value` attribute is *not the
   same* as the enum member itself, although it is equivalent and will compare
   equal.
5. A ``data type`` is a mixin that defines :meth:`__new__`, or a
   :class:`~dataclasses.dataclass`
6. %-style formatting:  ``%s`` and ``%r`` call the :class:`Enum` class's
   :meth:`__str__` and :meth:`__repr__` respectively; other codes (such as
   ``%i`` or ``%h`` for IntEnum) treat the enum member as its mixed-in type.
7. :ref:`Formatted string literals <f-strings>`, :meth:`str.format`,
   and :func:`format` will use the enum's :meth:`__str__` method.

.. note::

   Because :class:`IntEnum`, :class:`IntFlag`, and :class:`StrEnum` are
   designed to be drop-in replacements for existing constants, their
   :meth:`__str__` method has been reset to their data types'
   :meth:`__str__` method.

.. _new-vs-init:

When to use :meth:`__new__` vs. :meth:`__init__`
------------------------------------------------

:meth:`__new__` must be used whenever you want to customize the actual value of
the :class:`Enum` member.  Any other modifications may go in either
:meth:`__new__` or :meth:`__init__`, with :meth:`__init__` being preferred.

For example, if you want to pass several items to the constructor, but only
want one of them to be the value::

    >>> class Coordinate(bytes, Enum):
    ...     """
    ...     Coordinate with binary codes that can be indexed by the int code.
    ...     """
    ...     def __new__(cls, value, label, unit):
    ...         obj = bytes.__new__(cls, [value])
    ...         obj._value_ = value
    ...         obj.label = label
    ...         obj.unit = unit
    ...         return obj
    ...     PX = (0, 'P.X', 'km')
    ...     PY = (1, 'P.Y', 'km')
    ...     VX = (2, 'V.X', 'km/s')
    ...     VY = (3, 'V.Y', 'km/s')
    ...

    >>> print(Coordinate['PY'])
    Coordinate.PY

    >>> print(Coordinate(3))
    Coordinate.VY

.. warning::

    *Do not* call ``super().__new__()``, as the lookup-only ``__new__`` is the one
    that is found; instead, use the data type directly.


Finer Points
^^^^^^^^^^^^

Supported ``__dunder__`` names
""""""""""""""""""""""""""""""

:attr:`__members__` is a read-only ordered mapping of ``member_name``:``member``
items.  It is only available on the class.

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


Supported ``_sunder_`` names
""""""""""""""""""""""""""""

- :attr:`~Enum._name_` -- name of the member
- :attr:`~Enum._value_` -- value of the member; can be set in ``__new__``
- :meth:`~Enum._missing_` -- a lookup function used when a value is not found;
  may be overridden
- :attr:`~Enum._ignore_` -- a list of names, either as a :class:`list` or a
  :class:`str`, that will not be transformed into members, and will be removed
  from the final class
- :meth:`~Enum._generate_next_value_` -- used to get an appropriate value for
  an enum member; may be overridden
- :meth:`~Enum._add_alias_` -- adds a new name as an alias to an existing
  member.
- :meth:`~Enum._add_value_alias_` -- adds a new value as an alias to an
  existing member.  See `MultiValueEnum`_ for an example.

  .. note::

     For standard :class:`Enum` classes the next value chosen is the highest
     value seen incremented by one.

     For :class:`Flag` classes the next value chosen will be the next highest
     power-of-two.

  .. versionchanged:: 3.13
     Prior versions would use the last seen value instead of the highest value.

.. versionadded:: 3.6 ``_missing_``, ``_order_``, ``_generate_next_value_``
.. versionadded:: 3.7 ``_ignore_``
.. versionadded:: 3.13 ``_add_alias_``, ``_add_value_alias_``

To help keep Python 2 / Python 3 code in sync an :attr:`_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::

    >>> class Color(Enum):
    ...     _order_ = 'RED GREEN BLUE'
    ...     RED = 1
    ...     BLUE = 3
    ...     GREEN = 2
    ...
    Traceback (most recent call last):
    ...
    TypeError: member order does not match _order_:
      ['RED', 'BLUE', 'GREEN']
      ['RED', 'GREEN', 'BLUE']

.. note::

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


_Private__names
"""""""""""""""

:ref:`Private names <private-name-mangling>` are not converted to enum members,
but remain normal attributes.

.. versionchanged:: 3.11


``Enum`` member type
""""""""""""""""""""

Enum members are instances of their enum class, and are normally accessed as
``EnumClass.member``.  In certain situations, such as writing custom enum
behavior, being able to access one member directly from another is useful,
and is supported; however, in order to avoid name clashes between member names
and attributes/methods from mixed-in classes, upper-case names are strongly
recommended.

.. versionchanged:: 3.5


Creating members that are mixed with other data types
"""""""""""""""""""""""""""""""""""""""""""""""""""""

When subclassing other data types, such as :class:`int` or :class:`str`, with
an :class:`Enum`, all values after the ``=`` are passed to that data type's
constructor.  For example::

    >>> class MyEnum(IntEnum):      # help(int) -> int(x, base=10) -> integer
    ...     example = '11', 16      # so x='11' and base=16
    ...
    >>> MyEnum.example.value        # and hex(11) is...
    17


Boolean value of ``Enum`` classes and members
"""""""""""""""""""""""""""""""""""""""""""""

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

    def __bool__(self):
        return bool(self.value)

Plain :class:`Enum` classes always evaluate as :data:`True`.


``Enum`` classes with methods
"""""""""""""""""""""""""""""

If you give your enum subclass extra methods, like the `Planet`_
class below, those methods will show up in a :func:`dir` of the member,
but not of the class::

    >>> dir(Planet)                         # doctest: +SKIP
    ['EARTH', 'JUPITER', 'MARS', 'MERCURY', 'NEPTUNE', 'SATURN', 'URANUS', 'VENUS', '__class__', '__doc__', '__members__', '__module__']
    >>> dir(Planet.EARTH)                   # doctest: +SKIP
    ['__class__', '__doc__', '__module__', 'mass', 'name', 'radius', 'surface_gravity', 'value']


Combining members of ``Flag``
"""""""""""""""""""""""""""""

Iterating over a combination of :class:`Flag` members will only return the members that
are comprised of a single bit::

    >>> class Color(Flag):
    ...     RED = auto()
    ...     GREEN = auto()
    ...     BLUE = auto()
    ...     MAGENTA = RED | BLUE
    ...     YELLOW = RED | GREEN
    ...     CYAN = GREEN | BLUE
    ...
    >>> Color(3)  # named combination
    <Color.YELLOW: 3>
    >>> Color(7)      # not named combination
    <Color.RED|GREEN|BLUE: 7>


``Flag`` and ``IntFlag`` minutia
""""""""""""""""""""""""""""""""

Using the following snippet for our examples::

    >>> class Color(IntFlag):
    ...     BLACK = 0
    ...     RED = 1
    ...     GREEN = 2
    ...     BLUE = 4
    ...     PURPLE = RED | BLUE
    ...     WHITE = RED | GREEN | BLUE
    ...

the following are true:

- single-bit flags are canonical
- multi-bit and zero-bit flags are aliases
- only canonical flags are returned during iteration::

    >>> list(Color.WHITE)
    [<Color.RED: 1>, <Color.GREEN: 2>, <Color.BLUE: 4>]

- negating a flag or flag set returns a new flag/flag set with the
  corresponding positive integer value::

    >>> Color.BLUE
    <Color.BLUE: 4>

    >>> ~Color.BLUE
    <Color.RED|GREEN: 3>

- names of pseudo-flags are constructed from their members' names::

    >>> (Color.RED | Color.GREEN).name
    'RED|GREEN'

- multi-bit flags, aka aliases, can be returned from operations::

    >>> Color.RED | Color.BLUE
    <Color.PURPLE: 5>

    >>> Color(7)  # or Color(-1)
    <Color.WHITE: 7>

    >>> Color(0)
    <Color.BLACK: 0>

- membership / containment checking: zero-valued flags are always considered
  to be contained::

    >>> Color.BLACK in Color.WHITE
    True

  otherwise, only if all bits of one flag are in the other flag will True
  be returned::

    >>> Color.PURPLE in Color.WHITE
    True

    >>> Color.GREEN in Color.PURPLE
    False

There is a new boundary mechanism that controls how out-of-range / invalid
bits are handled: ``STRICT``, ``CONFORM``, ``EJECT``, and ``KEEP``:

* STRICT --> raises an exception when presented with invalid values
* CONFORM --> discards any invalid bits
* EJECT --> lose Flag status and become a normal int with the given value
* KEEP --> keep the extra bits

  - keeps Flag status and extra bits
  - extra bits do not show up in iteration
  - extra bits do show up in repr() and str()

The default for Flag is ``STRICT``, the default for ``IntFlag`` is ``EJECT``,
and the default for ``_convert_`` is ``KEEP`` (see ``ssl.Options`` for an
example of when ``KEEP`` is needed).


.. _enum-class-differences:

How are Enums and Flags different?
----------------------------------

Enums have a custom metaclass that affects many aspects of both derived :class:`Enum`
classes and their instances (members).


Enum Classes
^^^^^^^^^^^^

The :class:`EnumType` metaclass is responsible for providing the
:meth:`__contains__`, :meth:`__dir__`, :meth:`__iter__` and other methods that
allow one to do things with an :class:`Enum` class that fail on a typical
class, such as ``list(Color)`` or ``some_enum_var in Color``.  :class:`EnumType` is
responsible for ensuring that various other methods on the final :class:`Enum`
class are correct (such as :meth:`__new__`, :meth:`__getnewargs__`,
:meth:`__str__` and :meth:`__repr__`).

Flag Classes
^^^^^^^^^^^^

Flags have an expanded view of aliasing: to be canonical, the value of a flag
needs to be a power-of-two value, and not a duplicate name.  So, in addition to the
:class:`Enum` definition of alias, a flag with no value (a.k.a. ``0``) or with more than one
power-of-two value (e.g. ``3``) is considered an alias.

Enum Members (aka instances)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

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

Flag Members
^^^^^^^^^^^^

Flag members can be iterated over just like the :class:`Flag` class, and only the
canonical members will be returned.  For example::

    >>> list(Color)
    [<Color.RED: 1>, <Color.GREEN: 2>, <Color.BLUE: 4>]

(Note that ``BLACK``, ``PURPLE``, and ``WHITE`` do not show up.)

Inverting a flag member returns the corresponding positive value,
rather than a negative value --- for example::

    >>> ~Color.RED
    <Color.GREEN|BLUE: 6>

Flag members have a length corresponding to the number of power-of-two values
they contain.  For example::

    >>> len(Color.PURPLE)
    2


.. _enum-cookbook:

Enum Cookbook
-------------


While :class:`Enum`, :class:`IntEnum`, :class:`StrEnum`, :class:`Flag`, and
:class:`IntFlag` 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.


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:

- use instances of :class:`auto` for the value
- use instances of :class:`object` as the value
- use a descriptive string as the value
- use a tuple as the value and a custom :meth:`__new__` to replace the
  tuple with an :class:`int` value

Using any of these methods signifies to the user that these values are not
important, and also enables one to add, remove, or reorder members without
having to renumber the remaining members.


Using :class:`auto`
"""""""""""""""""""

Using :class:`auto` would look like::

    >>> class Color(Enum):
    ...     RED = auto()
    ...     BLUE = auto()
    ...     GREEN = auto()
    ...
    >>> Color.GREEN
    <Color.GREEN: 3>


Using :class:`object`
"""""""""""""""""""""

Using :class:`object` would look like::

    >>> class Color(Enum):
    ...     RED = object()
    ...     GREEN = object()
    ...     BLUE = object()
    ...
    >>> Color.GREEN                         # doctest: +SKIP
    <Color.GREEN: <object object at 0x...>>

This is also a good example of why you might want to write your own
:meth:`__repr__`::

    >>> class Color(Enum):
    ...     RED = object()
    ...     GREEN = object()
    ...     BLUE = object()
    ...     def __repr__(self):
    ...         return "<%s.%s>" % (self.__class__.__name__, self._name_)
    ...
    >>> Color.GREEN
    <Color.GREEN>



Using a descriptive string
""""""""""""""""""""""""""

Using a string as the value would look like::

    >>> class Color(Enum):
    ...     RED = 'stop'
    ...     GREEN = 'go'
    ...     BLUE = 'too fast!'
    ...
    >>> Color.GREEN
    <Color.GREEN: 'go'>


Using a custom :meth:`__new__`
""""""""""""""""""""""""""""""

Using an auto-numbering :meth:`__new__` would look like::

    >>> class AutoNumber(Enum):
    ...     def __new__(cls):
    ...         value = len(cls.__members__) + 1
    ...         obj = object.__new__(cls)
    ...         obj._value_ = value
    ...         return obj
    ...
    >>> class Color(AutoNumber):
    ...     RED = ()
    ...     GREEN = ()
    ...     BLUE = ()
    ...
    >>> Color.GREEN
    <Color.GREEN: 2>

To make a more general purpose ``AutoNumber``, add ``*args`` to the signature::

    >>> class AutoNumber(Enum):
    ...     def __new__(cls, *args):      # this is the only change from above
    ...         value = len(cls.__members__) + 1
    ...         obj = object.__new__(cls)
    ...         obj._value_ = value
    ...         return obj
    ...

Then when you inherit from ``AutoNumber`` you can write your own ``__init__``
to handle any extra arguments::

    >>> class Swatch(AutoNumber):
    ...     def __init__(self, pantone='unknown'):
    ...         self.pantone = pantone
    ...     AUBURN = '3497'
    ...     SEA_GREEN = '1246'
    ...     BLEACHED_CORAL = () # New color, no Pantone code yet!
    ...
    >>> Swatch.SEA_GREEN
    <Swatch.SEA_GREEN: 2>
    >>> Swatch.SEA_GREEN.pantone
    '1246'
    >>> Swatch.BLEACHED_CORAL.pantone
    'unknown'

.. note::

    The :meth:`__new__` method, if defined, is used during creation of the Enum
    members; it is then replaced by Enum's :meth:`__new__` which is used after
    class creation for lookup of existing members.

.. warning::

    *Do not* call ``super().__new__()``, as the lookup-only ``__new__`` is the one
    that is found; instead, use the data type directly -- e.g.::

       obj = int.__new__(cls, value)


OrderedEnum
^^^^^^^^^^^

An ordered enumeration that is not based on :class:`IntEnum` and so maintains
the normal :class:`Enum` invariants (such as not being comparable to other
enumerations)::

    >>> class OrderedEnum(Enum):
    ...     def __ge__(self, other):
    ...         if self.__class__ is other.__class__:
    ...             return self.value >= other.value
    ...         return NotImplemented
    ...     def __gt__(self, other):
    ...         if self.__class__ is other.__class__:
    ...             return self.value > other.value
    ...         return NotImplemented
    ...     def __le__(self, other):
    ...         if self.__class__ is other.__class__:
    ...             return self.value <= other.value
    ...         return NotImplemented
    ...     def __lt__(self, other):
    ...         if self.__class__ is other.__class__:
    ...             return self.value < other.value
    ...         return NotImplemented
    ...
    >>> class Grade(OrderedEnum):
    ...     A = 5
    ...     B = 4
    ...     C = 3
    ...     D = 2
    ...     F = 1
    ...
    >>> Grade.C < Grade.A
    True


DuplicateFreeEnum
^^^^^^^^^^^^^^^^^

Raises an error if a duplicate member value is found instead of creating an
alias::

    >>> class DuplicateFreeEnum(Enum):
    ...     def __init__(self, *args):
    ...         cls = self.__class__
    ...         if any(self.value == e.value for e in cls):
    ...             a = self.name
    ...             e = cls(self.value).name
    ...             raise ValueError(
    ...                 "aliases not allowed in DuplicateFreeEnum:  %r --> %r"
    ...                 % (a, e))
    ...
    >>> class Color(DuplicateFreeEnum):
    ...     RED = 1
    ...     GREEN = 2
    ...     BLUE = 3
    ...     GRENE = 2
    ...
    Traceback (most recent call last):
      ...
    ValueError: aliases not allowed in DuplicateFreeEnum:  'GRENE' --> 'GREEN'

.. note::

    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 :func:`unique` decorator can be used instead.


MultiValueEnum
^^^^^^^^^^^^^^^^^

Supports having more than one value per member::

    >>> class MultiValueEnum(Enum):
    ...     def __new__(cls, value, *values):
    ...         self = object.__new__(cls)
    ...         self._value_ = value
    ...         for v in values:
    ...             self._add_value_alias_(v)
    ...         return self
    ...
    >>> class DType(MultiValueEnum):
    ...     float32 = 'f', 8
    ...     double64 = 'd', 9
    ...
    >>> DType('f')
    <DType.float32: 'f'>
    >>> DType(9)
    <DType.double64: 'd'>


Planet
^^^^^^

If :meth:`__new__` or :meth:`__init__` is defined, the value of the enum member
will be passed to those methods::

    >>> class Planet(Enum):
    ...     MERCURY = (3.303e+23, 2.4397e6)
    ...     VENUS   = (4.869e+24, 6.0518e6)
    ...     EARTH   = (5.976e+24, 6.37814e6)
    ...     MARS    = (6.421e+23, 3.3972e6)
    ...     JUPITER = (1.9e+27,   7.1492e7)
    ...     SATURN  = (5.688e+26, 6.0268e7)
    ...     URANUS  = (8.686e+25, 2.5559e7)
    ...     NEPTUNE = (1.024e+26, 2.4746e7)
    ...     def __init__(self, mass, radius):
    ...         self.mass = mass       # in kilograms
    ...         self.radius = radius   # in meters
    ...     @property
    ...     def surface_gravity(self):
    ...         # universal gravitational constant  (m3 kg-1 s-2)
    ...         G = 6.67300E-11
    ...         return G * self.mass / (self.radius * self.radius)
    ...
    >>> Planet.EARTH.value
    (5.976e+24, 6378140.0)
    >>> Planet.EARTH.surface_gravity
    9.802652743337129

.. _enum-time-period:

TimePeriod
^^^^^^^^^^

An example to show the :attr:`_ignore_` attribute in use::

    >>> from datetime import timedelta
    >>> class Period(timedelta, Enum):
    ...     "different lengths of time"
    ...     _ignore_ = 'Period i'
    ...     Period = vars()
    ...     for i in range(367):
    ...         Period['day_%d' % i] = i
    ...
    >>> list(Period)[:2]
    [<Period.day_0: datetime.timedelta(0)>, <Period.day_1: datetime.timedelta(days=1)>]
    >>> list(Period)[-2:]
    [<Period.day_365: datetime.timedelta(days=365)>, <Period.day_366: datetime.timedelta(days=366)>]


.. _enumtype-examples:

Subclassing EnumType
--------------------

While most enum needs can be met by customizing :class:`Enum` subclasses,
either with class decorators or custom functions, :class:`EnumType` can be
subclassed to provide a different Enum experience.
