Skip to content

Commit ebd4400

Browse files
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 d9a43e2)
1 parent f881c86 commit ebd4400

File tree

5 files changed

+21
-0
lines changed

5 files changed

+21
-0
lines changed

Doc/library/enum.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,10 @@ overridden::
273273
the next :class:`int` in sequence with the last :class:`int` provided, but
274274
the way it does this is an implementation detail and may change.
275275

276+
.. note::
277+
278+
The :meth:`_generate_next_value_` method must be defined before any members.
279+
276280
Iteration
277281
---------
278282

Lib/enum.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ def __init__(self):
6666
self._member_names = []
6767
self._last_values = []
6868
self._ignore = []
69+
self._auto_called = False
6970

7071
def __setitem__(self, key, value):
7172
"""Changes anything not dundered or not a descriptor.
@@ -83,6 +84,9 @@ def __setitem__(self, key, value):
8384
):
8485
raise ValueError('_names_ are reserved for future Enum use')
8586
if key == '_generate_next_value_':
87+
# check if members already defined as auto()
88+
if self._auto_called:
89+
raise TypeError("_generate_next_value_ must be defined before members")
8690
setattr(self, '_generate_next_value', value)
8791
elif key == '_ignore_':
8892
if isinstance(value, str):
@@ -106,6 +110,7 @@ def __setitem__(self, key, value):
106110
# enum overwriting a descriptor?
107111
raise TypeError('%r already defined as: %r' % (key, self[key]))
108112
if isinstance(value, auto):
113+
self._auto_called = True
109114
if value.value == _auto_null:
110115
value.value = self._generate_next_value(key, 1, len(self._member_names), self._last_values[:])
111116
value = value.value

Lib/test/test_enum.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1710,6 +1710,16 @@ class Color(Enum):
17101710
self.assertEqual(Color.blue.value, 2)
17111711
self.assertEqual(Color.green.value, 3)
17121712

1713+
def test_auto_order(self):
1714+
with self.assertRaises(TypeError):
1715+
class Color(Enum):
1716+
red = auto()
1717+
green = auto()
1718+
blue = auto()
1719+
def _generate_next_value_(name, start, count, last):
1720+
return name
1721+
1722+
17131723
def test_duplicate_auto(self):
17141724
class Dupes(Enum):
17151725
first = primero = auto()

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,6 +1185,7 @@ Adam Olsen
11851185
Bryan Olson
11861186
Grant Olson
11871187
Koray Oner
1188+
Ethan Onstott
11881189
Piet van Oostrum
11891190
Tomas Oppelstrup
11901191
Jason Orendorff
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Raise TypeError when _generate_next_value_ is defined after members. Patch by Ethan Onstott.

0 commit comments

Comments
 (0)