]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-100098: [Enum] insist on actual tuples, no subclasses, for auto (GH-100099)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Thu, 8 Dec 2022 07:21:29 +0000 (23:21 -0800)
committerGitHub <noreply@github.com>
Thu, 8 Dec 2022 07:21:29 +0000 (23:21 -0800)
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@stoneleaf.us>
Lib/enum.py
Lib/test/test_enum.py
Misc/NEWS.d/next/Library/2022-12-08-06-18-06.gh-issue-100098.uBvPlp.rst [new file with mode: 0644]

index 1efddfa1a0acc64481bc653bcbb0882a58b916d1..7ad599bb1e62e3e7860d3874481680ebc349d839 100644 (file)
@@ -430,7 +430,9 @@ class _EnumDict(dict):
             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):
index a9b80ad0d3dbc3dcfe6c82a0a4b30566a4a41dee..0e2da1d64c1950e618073fe9131074da06328735 100644 (file)
@@ -2727,6 +2727,19 @@ class TestSpecial(unittest.TestCase):
         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 (file)
index 0000000..256f2bc
--- /dev/null
@@ -0,0 +1 @@
+Fix ``tuple`` subclasses being cast to ``tuple`` when used as enum values.