diff options
author | 2020-06-11 14:48:47 -0700 | |
---|---|---|
committer | 2020-06-11 14:48:47 -0700 | |
commit | ebd44003c9e206755e5e28716242ed8941495a62 (patch) | |
tree | 8987c884111376a216c81876db640c595371396f | |
parent | bpo-29620: iterate over a copy of sys.modules (GH-4800) (GH-20817) (diff) | |
download | cpython-ebd44003c9e206755e5e28716242ed8941495a62.tar.gz cpython-ebd44003c9e206755e5e28716242ed8941495a62.tar.bz2 cpython-ebd44003c9e206755e5e28716242ed8941495a62.zip |
bpo-40025: Require _generate_next_value_ to be defined before members (GH-19762)
require `_generate_next_value_` to be defined before members
(cherry picked from commit d9a43e20facdf4ad10186f820601c6580e1baa80)
-rw-r--r-- | Doc/library/enum.rst | 4 | ||||
-rw-r--r-- | Lib/enum.py | 5 | ||||
-rw-r--r-- | Lib/test/test_enum.py | 10 | ||||
-rw-r--r-- | Misc/ACKS | 1 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2020-03-21-05-26-38.bpo-40025.DTLtyq.rst | 1 |
5 files changed, 21 insertions, 0 deletions
diff --git a/Doc/library/enum.rst b/Doc/library/enum.rst index 38221199dcd..e340f3ba643 100644 --- a/Doc/library/enum.rst +++ b/Doc/library/enum.rst @@ -273,6 +273,10 @@ overridden:: the next :class:`int` in sequence with the last :class:`int` provided, but the way it does this is an implementation detail and may change. +.. note:: + + The :meth:`_generate_next_value_` method must be defined before any members. + Iteration --------- diff --git a/Lib/enum.py b/Lib/enum.py index d0b03b4aa56..83e6410107c 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -66,6 +66,7 @@ class _EnumDict(dict): self._member_names = [] self._last_values = [] self._ignore = [] + self._auto_called = False def __setitem__(self, key, value): """Changes anything not dundered or not a descriptor. @@ -83,6 +84,9 @@ class _EnumDict(dict): ): raise ValueError('_names_ are reserved for future Enum use') if key == '_generate_next_value_': + # check if members already defined as auto() + if self._auto_called: + raise TypeError("_generate_next_value_ must be defined before members") setattr(self, '_generate_next_value', value) elif key == '_ignore_': if isinstance(value, str): @@ -106,6 +110,7 @@ class _EnumDict(dict): # enum overwriting a descriptor? raise TypeError('%r already defined as: %r' % (key, self[key])) if isinstance(value, auto): + self._auto_called = True if value.value == _auto_null: value.value = self._generate_next_value(key, 1, len(self._member_names), self._last_values[:]) value = value.value diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py index 29a429ccd99..d9260f4cb47 100644 --- a/Lib/test/test_enum.py +++ b/Lib/test/test_enum.py @@ -1710,6 +1710,16 @@ class TestEnum(unittest.TestCase): self.assertEqual(Color.blue.value, 2) self.assertEqual(Color.green.value, 3) + def test_auto_order(self): + with self.assertRaises(TypeError): + class Color(Enum): + red = auto() + green = auto() + blue = auto() + def _generate_next_value_(name, start, count, last): + return name + + def test_duplicate_auto(self): class Dupes(Enum): first = primero = auto() diff --git a/Misc/ACKS b/Misc/ACKS index ce269edbd51..a6da4f12898 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1185,6 +1185,7 @@ Adam Olsen Bryan Olson Grant Olson Koray Oner +Ethan Onstott Piet van Oostrum Tomas Oppelstrup Jason Orendorff diff --git a/Misc/NEWS.d/next/Library/2020-03-21-05-26-38.bpo-40025.DTLtyq.rst b/Misc/NEWS.d/next/Library/2020-03-21-05-26-38.bpo-40025.DTLtyq.rst new file mode 100644 index 00000000000..7b699de4e07 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-03-21-05-26-38.bpo-40025.DTLtyq.rst @@ -0,0 +1 @@ +Raise TypeError when _generate_next_value_ is defined after members. Patch by Ethan Onstott.
\ No newline at end of file |