Skip to content

Commit 23f9995

Browse files
ethanfurmanAlexWaygoodsobolevn
authored andcommitted
pythongh-112328: [Enum] Make some private attributes public. (pythonGH-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 <[email protected]> Co-authored-by: Nikita Sobolev <[email protected]>
1 parent 9cadca5 commit 23f9995

File tree

5 files changed

+301
-117
lines changed

5 files changed

+301
-117
lines changed

Doc/howto/enum.rst

+47-20
Original file line numberDiff line numberDiff line change
@@ -868,16 +868,16 @@ Others
868868
While :class:`IntEnum` is part of the :mod:`enum` module, it would be very
869869
simple to implement independently::
870870

871-
class IntEnum(int, Enum):
871+
class IntEnum(int, ReprEnum): # or Enum instead of ReprEnum
872872
pass
873873

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

877877
Some rules:
878878

879-
1. When subclassing :class:`Enum`, mix-in types must appear before
880-
:class:`Enum` itself in the sequence of bases, as in the :class:`IntEnum`
879+
1. When subclassing :class:`Enum`, mix-in types must appear before the
880+
:class:`Enum` class itself in the sequence of bases, as in the :class:`IntEnum`
881881
example above.
882882
2. Mix-in types must be subclassable. For example, :class:`bool` and
883883
:class:`range` are not subclassable and will throw an error during Enum
@@ -961,30 +961,34 @@ all the members are created it is no longer used.
961961
Supported ``_sunder_`` names
962962
""""""""""""""""""""""""""""
963963

964-
- ``_name_`` -- name of the member
965-
- ``_value_`` -- value of the member; can be set / modified in ``__new__``
964+
- :attr:`~Enum._name_` -- name of the member
965+
- :attr:`~Enum._value_` -- value of the member; can be set in ``__new__``
966+
- :meth:`~Enum._missing_` -- a lookup function used when a value is not found;
967+
may be overridden
968+
- :attr:`~Enum._ignore_` -- a list of names, either as a :class:`list` or a
969+
:class:`str`, that will not be transformed into members, and will be removed
970+
from the final class
971+
- :meth:`~Enum._generate_next_value_` -- used to get an appropriate value for
972+
an enum member; may be overridden
973+
- :meth:`~Enum._add_alias_` -- adds a new name as an alias to an existing
974+
member.
975+
- :meth:`~Enum._add_value_alias_` -- adds a new value as an alias to an
976+
existing member. See `MultiValueEnum`_ for an example.
966977

967-
- ``_missing_`` -- a lookup function used when a value is not found; may be
968-
overridden
969-
- ``_ignore_`` -- a list of names, either as a :class:`list` or a :class:`str`,
970-
that will not be transformed into members, and will be removed from the final
971-
class
972-
- ``_order_`` -- used in Python 2/3 code to ensure member order is consistent
973-
(class attribute, removed during class creation)
974-
- ``_generate_next_value_`` -- used by the `Functional API`_ and by
975-
:class:`auto` to get an appropriate value for an enum member; may be
976-
overridden
978+
.. note::
977979

978-
.. note::
980+
For standard :class:`Enum` classes the next value chosen is the highest
981+
value seen incremented by one.
979982

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

983-
For :class:`Flag` classes the next value chosen will be the next highest
984-
power-of-two, regardless of the last value seen.
986+
.. versionchanged:: 3.13
987+
Prior versions would use the last seen value instead of the highest value.
985988

986989
.. versionadded:: 3.6 ``_missing_``, ``_order_``, ``_generate_next_value_``
987990
.. versionadded:: 3.7 ``_ignore_``
991+
.. versionadded:: 3.13 ``_add_alias_``, ``_add_value_alias_``
988992

989993
To help keep Python 2 / Python 3 code in sync an :attr:`_order_` attribute can
990994
be provided. It will be checked against the actual order of the enumeration
@@ -1447,6 +1451,29 @@ alias::
14471451
disallowing aliases, the :func:`unique` decorator can be used instead.
14481452

14491453

1454+
MultiValueEnum
1455+
^^^^^^^^^^^^^^^^^
1456+
1457+
Supports having more than one value per member::
1458+
1459+
>>> class MultiValueEnum(Enum):
1460+
... def __new__(cls, value, *values):
1461+
... self = object.__new__(cls)
1462+
... self._value_ = value
1463+
... for v in values:
1464+
... self._add_value_alias_(v)
1465+
... return self
1466+
...
1467+
>>> class DType(MultiValueEnum):
1468+
... float32 = 'f', 8
1469+
... double64 = 'd', 9
1470+
...
1471+
>>> DType('f')
1472+
<DType.float32: 'f'>
1473+
>>> DType(9)
1474+
<DType.double64: 'd'>
1475+
1476+
14501477
Planet
14511478
^^^^^^
14521479

Doc/library/enum.rst

+39-21
Original file line numberDiff line numberDiff line change
@@ -235,16 +235,30 @@ Data Types
235235
>>> len(Color)
236236
3
237237

238+
.. attribute:: EnumType.__members__
239+
240+
Returns a mapping of every enum name to its member, including aliases
241+
238242
.. method:: EnumType.__reversed__(cls)
239243

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

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

249+
.. method:: EnumType._add_alias_
250+
251+
Adds a new name as an alias to an existing member. Raises a
252+
:exc:`NameError` if the name is already assigned to a different member.
253+
254+
.. method:: EnumType._add_value_alias_
255+
256+
Adds a new value as an alias to an existing member. Raises a
257+
:exc:`ValueError` if the value is already linked with a different member.
258+
245259
.. versionadded:: 3.11
246260

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

249263

250264
.. class:: Enum
@@ -323,7 +337,7 @@ Data Types
323337
>>> PowersOfThree.SECOND.value
324338
9
325339

326-
.. method:: Enum.__init_subclass__(cls, **kwds)
340+
.. method:: Enum.__init_subclass__(cls, \**kwds)
327341

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

550564
.. method:: __invert__(self):
551565

552-
Returns all the flags in *type(self)* that are not in self::
566+
Returns all the flags in *type(self)* that are not in *self*::
553567

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

772-
:meth:`~object.__new__`, if specified, must create and return the enum members; it is
773-
also a very good idea to set the member's :attr:`!_value_` appropriately. Once
774-
all the members are created it is no longer used.
786+
:meth:`~object.__new__`, if specified, must create and return the enum members;
787+
it is also a very good idea to set the member's :attr:`!_value_` appropriately.
788+
Once all the members are created it is no longer used.
775789

776790

777791
Supported ``_sunder_`` names
778792
""""""""""""""""""""""""""""
779793

780-
- ``_name_`` -- name of the member
781-
- ``_value_`` -- value of the member; can be set / modified in ``__new__``
782-
783-
- ``_missing_`` -- a lookup function used when a value is not found; may be
784-
overridden
785-
- ``_ignore_`` -- a list of names, either as a :class:`list` or a :class:`str`,
786-
that will not be transformed into members, and will be removed from the final
787-
class
788-
- ``_order_`` -- used in Python 2/3 code to ensure member order is consistent
789-
(class attribute, removed during class creation)
790-
- ``_generate_next_value_`` -- used to get an appropriate value for an enum
791-
member; may be overridden
794+
- :meth:`~EnumType._add_alias_` -- adds a new name as an alias to an existing
795+
member.
796+
- :meth:`~EnumType._add_value_alias_` -- adds a new value as an alias to an
797+
existing member.
798+
- :attr:`~Enum._name_` -- name of the member
799+
- :attr:`~Enum._value_` -- value of the member; can be set in ``__new__``
800+
- :meth:`~Enum._missing_` -- a lookup function used when a value is not found;
801+
may be overridden
802+
- :attr:`~Enum._ignore_` -- a list of names, either as a :class:`list` or a
803+
:class:`str`, that will not be transformed into members, and will be removed
804+
from the final class
805+
- :attr:`~Enum._order_` -- used in Python 2/3 code to ensure member order is
806+
consistent (class attribute, removed during class creation)
807+
- :meth:`~Enum._generate_next_value_` -- used to get an appropriate value for
808+
an enum member; may be overridden
792809

793810
.. note::
794811

795-
For standard :class:`Enum` classes the next value chosen is the last value seen
796-
incremented by one.
812+
For standard :class:`Enum` classes the next value chosen is the highest
813+
value seen incremented by one.
797814

798815
For :class:`Flag` classes the next value chosen will be the next highest
799-
power-of-two, regardless of the last value seen.
816+
power-of-two.
800817

801818
.. versionadded:: 3.6 ``_missing_``, ``_order_``, ``_generate_next_value_``
802819
.. versionadded:: 3.7 ``_ignore_``
820+
.. versionadded:: 3.13 ``_add_alias_``, ``_add_value_alias_``
803821

804822
---------------
805823

0 commit comments

Comments
 (0)