summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2020-06-11 14:48:47 -0700
committerGitHub <noreply@github.com>2020-06-11 14:48:47 -0700
commitebd44003c9e206755e5e28716242ed8941495a62 (patch)
tree8987c884111376a216c81876db640c595371396f
parentbpo-29620: iterate over a copy of sys.modules (GH-4800) (GH-20817) (diff)
downloadcpython-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.rst4
-rw-r--r--Lib/enum.py5
-rw-r--r--Lib/test/test_enum.py10
-rw-r--r--Misc/ACKS1
-rw-r--r--Misc/NEWS.d/next/Library/2020-03-21-05-26-38.bpo-40025.DTLtyq.rst1
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