]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-41889: [Enum] fix multiple-inheritance regression (GH-22487) (GH-23672)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Mon, 7 Dec 2020 23:50:14 +0000 (15:50 -0800)
committerGitHub <noreply@github.com>
Mon, 7 Dec 2020 23:50:14 +0000 (15:50 -0800)
(cherry picked from commit c266736ec1f9ebef38b134ceb4832df015711b38)

Lib/enum.py
Lib/test/test_enum.py
Misc/NEWS.d/next/Library/2020-10-01-16-17-11.bpo-41889.qLkNh8.rst [new file with mode: 0644]

index de9ed4c1ec371129c80ea0392c3dc093b87c603c..da809e2689114bebb43d1e708b59d04764f5cd0e 100644 (file)
@@ -145,8 +145,9 @@ class EnumMeta(type):
         for key in ignore:
             classdict.pop(key, None)
         member_type, first_enum = metacls._get_mixins_(cls, bases)
-        __new__, save_new, use_args = metacls._find_new_(classdict, member_type,
-                                                        first_enum)
+        __new__, save_new, use_args = metacls._find_new_(
+                classdict, member_type, first_enum,
+                )
 
         # save enum items into separate mapping so they don't get baked into
         # the new class
@@ -506,12 +507,16 @@ class EnumMeta(type):
                 for base in chain.__mro__:
                     if base is object:
                         continue
+                    elif issubclass(base, Enum):
+                        if base._member_type_ is not object:
+                            data_types.append(base._member_type_)
+                            break
                     elif '__new__' in base.__dict__:
                         if issubclass(base, Enum):
                             continue
                         data_types.append(candidate or base)
                         break
-                    elif not issubclass(base, Enum):
+                    else:
                         candidate = base
             if len(data_types) > 1:
                 raise TypeError('%r: too many data types: %r' % (class_name, data_types))
index 745962a1e66fe9770ab6ed62a0a4b0a6e1a24cc8..7f6e6bf092b6f5c881ae90e179d9acac65fbd26d 100644 (file)
@@ -2000,6 +2000,32 @@ class TestEnum(unittest.TestCase):
             REVERT_ALL = "REVERT_ALL"
             RETRY = "RETRY"
 
+    def test_multiple_mixin_inherited(self):
+        class MyInt(int):
+            def __new__(cls, value):
+                return super().__new__(cls, value)
+
+        class HexMixin:
+            def __repr__(self):
+                return hex(self)
+
+        class MyIntEnum(HexMixin, MyInt, enum.Enum):
+            pass
+
+        class Foo(MyIntEnum):
+            TEST = 1
+        self.assertTrue(isinstance(Foo.TEST, MyInt))
+        self.assertEqual(repr(Foo.TEST), "0x1")
+
+        class Fee(MyIntEnum):
+            TEST = 1
+            def __new__(cls, value):
+                value += 1
+                member = int.__new__(cls, value)
+                member._value_ = value
+                return member
+        self.assertEqual(Fee.TEST, 2)
+
     def test_empty_globals(self):
         # bpo-35717: sys._getframe(2).f_globals['__name__'] fails with KeyError
         # when using compile and exec because f_globals is empty
diff --git a/Misc/NEWS.d/next/Library/2020-10-01-16-17-11.bpo-41889.qLkNh8.rst b/Misc/NEWS.d/next/Library/2020-10-01-16-17-11.bpo-41889.qLkNh8.rst
new file mode 100644 (file)
index 0000000..768865a
--- /dev/null
@@ -0,0 +1 @@
+Enum: fix regression involving inheriting a multiply-inherited enum