[Python-checkins] gh-100098: [Enum] insist on actual tuples, no subclasses, for auto (GH-100099)
miss-islington
webhook-mailer at python.org
Thu Dec 8 02:21:55 EST 2022
https://github.com/python/cpython/commit/d4426c829565e3ef922c091ee9bd48bc556f2550
commit: d4426c829565e3ef922c091ee9bd48bc556f2550
branch: 3.11
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: miss-islington <31488909+miss-islington at users.noreply.github.com>
date: 2022-12-07T23:21:29-08:00
summary:
gh-100098: [Enum] insist on actual tuples, no subclasses, for auto (GH-100099)
When checking for auto() instances, only top-level usage is supported,
which means either alone or as part of a regular tuple. Other
containers, such as lists, dicts, or namedtuples, will not have auto()
transformed into a value.
(cherry picked from commit ded02ca54d7bfa32c8eab0871d56e4547cd356eb)
Co-authored-by: Ethan Furman <ethan at stoneleaf.us>
files:
A Misc/NEWS.d/next/Library/2022-12-08-06-18-06.gh-issue-100098.uBvPlp.rst
M Lib/enum.py
M Lib/test/test_enum.py
diff --git a/Lib/enum.py b/Lib/enum.py
index 1efddfa1a0ac..7ad599bb1e62 100644
--- a/Lib/enum.py
+++ b/Lib/enum.py
@@ -430,7 +430,9 @@ def __setitem__(self, key, value):
if isinstance(value, auto):
single = True
value = (value, )
- if isinstance(value, tuple):
+ if type(value) is tuple and any(isinstance(v, auto) for v in value):
+ # insist on an actual tuple, no subclasses, in keeping with only supporting
+ # top-level auto() usage (not contained in any other data structure)
auto_valued = []
for v in value:
if isinstance(v, auto):
diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py
index a9b80ad0d3db..0e2da1d64c19 100644
--- a/Lib/test/test_enum.py
+++ b/Lib/test/test_enum.py
@@ -2727,6 +2727,19 @@ class MyIntFlag(IntFlag):
self.assertEqual(deep, flags)
self.assertEqual(copied.value, 1 | 2 | 8)
+ def test_namedtuple_as_value(self):
+ from collections import namedtuple
+ TTuple = namedtuple('TTuple', 'id a blist')
+ class NTEnum(Enum):
+ NONE = TTuple(0, 0, [])
+ A = TTuple(1, 2, [4])
+ B = TTuple(2, 4, [0, 1, 2])
+ self.assertEqual(repr(NTEnum.NONE), "<NTEnum.NONE: TTuple(id=0, a=0, blist=[])>")
+ self.assertEqual(NTEnum.NONE.value, TTuple(id=0, a=0, blist=[]))
+ self.assertEqual(
+ [x.value for x in NTEnum],
+ [TTuple(id=0, a=0, blist=[]), TTuple(id=1, a=2, blist=[4]), TTuple(id=2, a=4, blist=[0, 1, 2])],
+ )
class TestOrder(unittest.TestCase):
"test usage of the `_order_` attribute"
diff --git a/Misc/NEWS.d/next/Library/2022-12-08-06-18-06.gh-issue-100098.uBvPlp.rst b/Misc/NEWS.d/next/Library/2022-12-08-06-18-06.gh-issue-100098.uBvPlp.rst
new file mode 100644
index 000000000000..256f2bcd39f8
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2022-12-08-06-18-06.gh-issue-100098.uBvPlp.rst
@@ -0,0 +1 @@
+Fix ``tuple`` subclasses being cast to ``tuple`` when used as enum values.
More information about the Python-checkins
mailing list