10000 bpo-40025: Require _generate_next_value_ to be defined before members… · python/cpython@b5ecbf0 · GitHub
[go: up one dir, main page]

Skip to content

Commit b5ecbf0

Browse files
bpo-40025: Require _generate_next_value_ to be defined before members(GH-19763)
require `_generate_next_value_` to be defined before members
1 parent a285af7 commit b5ecbf0

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
@@ -60,6 +60,7 @@ def __init__(self):
6060
self._member_names = []
6161
self._last_values = []
6262
self._ignore = []
63+
self._auto_called = False
6364

6465
def __setitem__(self, key, value):
6566
"""Changes anything not dundered or not a descriptor.
@@ -77,6 +78,9 @@ def __setitem__(self, key, value):
7778
):
7879
raise ValueError('_names_ are reserved for future Enum use')
7980
if key == '_generate_next_value_':
81+
# check if members already defined as auto()
82+
if self._auto_called:
83+
raise TypeError("_generate_next_value_ must be defined before members")
8084
setattr(self, '_generate_next_value', value)
8185
elif key == '_ignore_':
8286
if isinstance(value, str):
@@ -100,6 +104,7 @@ def __setitem__(self, key, value):
100104
# enum overwriting a descriptor?
101105
raise TypeError('%r already defined as: %r' % (key, self[key]))
102106
if isinstance(value, auto):
107+
self._auto_called = True
103108
if value.value == _auto_null:
104109
value.value = self._generate_next_value(key, 1, len(self._member_names), self._last_values[:])
105110
value = value.value

Lib/test/test_enum.py

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

1705+
def test_auto_order(self):
1706+
with self.assertRaises(TypeError):
1707+
class Color(Enum):
1708+
red = auto()
1709+
green = auto()
1710+
blue = auto()
1711+
def _generate_next_value_(name, start, count, last):
1712+
return name
1713+
1714+
17051715
def test_duplicate_auto(self):
17061716
class Dupes(Enum):
17071717
first = primero = auto()

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,6 +1217,7 @@ Adam Olsen
12171217
Bryan Olson
12181218
Grant Olson
12191219
Koray Oner
1220+
Ethan Onstott
12201221
Piet van Oostrum
12211222
Tomas Oppelstrup
12221223
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)
0