Skip to content

Commit c266736

Browse files
authored
bpo-41889: [Enum] fix multiple-inheritance regression (GH-22487)
1 parent 2123373 commit c266736

File tree

3 files changed

+35
-3
lines changed

3 files changed

+35
-3
lines changed

Lib/enum.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,9 @@ def __new__(metacls, cls, bases, classdict):
146146
for key in ignore:
147147
classdict.pop(key, None)
148148
member_type, first_enum = metacls._get_mixins_(cls, bases)
149-
__new__, save_new, use_args = metacls._find_new_(classdict, member_type,
150-
first_enum)
149+
__new__, save_new, use_args = metacls._find_new_(
150+
classdict, member_type, first_enum,
151+
)
151152

152153
# save enum items into separate mapping so they don't get baked into
153154
# the new class
@@ -501,12 +502,16 @@ def _find_data_type(bases):
501502
for base in chain.__mro__:
502503
if base is object:
503504
continue
505+
elif issubclass(base, Enum):
506+
if base._member_type_ is not object:
507+
data_types.append(base._member_type_)
508+
break
504509
elif '__new__' in base.__dict__:
505510
if issubclass(base, Enum):
506511
continue
507512
data_types.append(candidate or base)
508513
break
509-
elif not issubclass(base, Enum):
514+
else:
510515
candidate = base
511516
if len(data_types) > 1:
512517
raise TypeError('%r: too many data types: %r' % (class_name, data_types))

Lib/test/test_enum.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2021,6 +2021,32 @@ class Decision2(MyEnum):
20212021
REVERT_ALL = "REVERT_ALL"
20222022
RETRY = "RETRY"
20232023

2024+
def test_multiple_mixin_inherited(self):
2025+
class MyInt(int):
2026+
def __new__(cls, value):
2027+
return super().__new__(cls, value)
2028+
2029+
class HexMixin:
2030+
def __repr__(self):
2031+
return hex(self)
2032+
2033+
class MyIntEnum(HexMixin, MyInt, enum.Enum):
2034+
pass
2035+
2036+
class Foo(MyIntEnum):
2037+
TEST = 1
2038+
self.assertTrue(isinstance(Foo.TEST, MyInt))
2039+
self.assertEqual(repr(Foo.TEST), "0x1")
2040+
2041+
class Fee(MyIntEnum):
2042+
TEST = 1
2043+
def __new__(cls, value):
2044+
value += 1
2045+
member = int.__new__(cls, value)
2046+
member._value_ = value
2047+
return member
2048+
self.assertEqual(Fee.TEST, 2)
2049+
20242050
def test_empty_globals(self):
20252051
# bpo-35717: sys._getframe(2).f_globals['__name__'] fails with KeyError
20262052
# when using compile and exec because f_globals is empty
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Enum: fix regression involving inheriting a multiply-inherited enum

0 commit comments

Comments
 (0)