Skip to content

Commit

Permalink
pythongh-112328: [Enum] Make some private attributes public. (pythonG…
Browse files Browse the repository at this point in the history
…H-112514)

* [Enum] Make some private attributes public.

- ``_EnumDict`` --> ``EnumDict``
- ``EnumDict._member_names`` --> ``EnumDict.member_names``
- ``Enum._add_alias_``
- ``Enum._add_value_alias_``

---------

Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
Co-authored-by: Nikita Sobolev <mail@sobolevn.me>
  • Loading branch information
3 people committed Dec 5, 2023
1 parent 563ccde commit de6bca9
Show file tree
Hide file tree
Showing 5 changed files with 301 additions and 117 deletions.
67 changes: 47 additions & 20 deletions Doc/howto/enum.rst
Original file line number Diff line number Diff line change
Expand Up @@ -868,16 +868,16 @@ Others
While :class:`IntEnum` is part of the :mod:`enum` module, it would be very
simple to implement independently::

class IntEnum(int, Enum):
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
:class:`Enum` itself in the sequence of bases, as in the :class:`IntEnum`
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
Expand Down Expand Up @@ -961,30 +961,34 @@ all the members are created it is no longer used.
Supported ``_sunder_`` names
""""""""""""""""""""""""""""

- ``_name_`` -- name of the member
- ``_value_`` -- value of the member; can be set / modified in ``__new__``
- :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.

- ``_missing_`` -- a lookup function used when a value is not found; may be
overridden
- ``_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
- ``_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
:class:`auto` to get an appropriate value for an enum member; may be
overridden
.. note::

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

For standard :class:`Enum` classes the next value chosen is the last value seen
incremented by one.
For :class:`Flag` classes the next value chosen will be the next highest
power-of-two.

For :class:`Flag` classes the next value chosen will be the next highest
power-of-two, regardless of the last value seen.
.. 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
Expand Down Expand Up @@ -1447,6 +1451,29 @@ alias::
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
^^^^^^

Expand Down
60 changes: 39 additions & 21 deletions Doc/library/enum.rst
Original file line number Diff line number Diff line change
Expand Up @@ -235,16 +235,30 @@ Data Types
>>> len(Color)
3

.. attribute:: EnumType.__members__

Returns a mapping of every enum name to its member, including aliases

.. method:: EnumType.__reversed__(cls)

Returns each member in *cls* in reverse definition order::

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

.. method:: EnumType._add_alias_

Adds a new name as an alias to an existing member. Raises a
:exc:`NameError` if the name is already assigned to a different member.

.. method:: EnumType._add_value_alias_

Adds a new value as an alias to an existing member. Raises a
:exc:`ValueError` if the value is already linked with a different member.

.. versionadded:: 3.11

Before 3.11 ``enum`` used ``EnumMeta`` type, which is kept as an alias.
Before 3.11 ``EnumType`` was called ``EnumMeta``, which is still available as an alias.


.. class:: Enum
Expand Down Expand Up @@ -323,7 +337,7 @@ Data Types
>>> PowersOfThree.SECOND.value
9

.. method:: Enum.__init_subclass__(cls, **kwds)
.. method:: Enum.__init_subclass__(cls, \**kwds)

A *classmethod* that is used to further configure subsequent subclasses.
By default, does nothing.
Expand Down Expand Up @@ -549,7 +563,7 @@ Data Types

.. method:: __invert__(self):

Returns all the flags in *type(self)* that are not in self::
Returns all the flags in *type(self)* that are not in *self*::

>>> ~white
<Color: 0>
Expand Down Expand Up @@ -769,37 +783,41 @@ Supported ``__dunder__`` names
:attr:`~EnumType.__members__` is a read-only ordered mapping of ``member_name``:``member``
items. It is only available on the class.

:meth:`~object.__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.
:meth:`~object.__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
""""""""""""""""""""""""""""

- ``_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
- ``_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
- ``_order_`` -- used in Python 2/3 code to ensure member order is consistent
(class attribute, removed during class creation)
- ``_generate_next_value_`` -- used to get an appropriate value for an enum
member; may be overridden
- :meth:`~EnumType._add_alias_` -- adds a new name as an alias to an existing
member.
- :meth:`~EnumType._add_value_alias_` -- adds a new value as an alias to an
existing member.
- :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
- :attr:`~Enum._order_` -- used in Python 2/3 code to ensure member order is
consistent (class attribute, removed during class creation)
- :meth:`~Enum._generate_next_value_` -- used to get an appropriate value for
an enum member; may be overridden

.. note::

For standard :class:`Enum` classes the next value chosen is the last value seen
incremented by one.
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, regardless of the last value seen.
power-of-two.

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

---------------

Expand Down

0 comments on commit de6bca9

Please sign in to comment.