Skip to content

Commit 699e5e4

Browse files
bpo-41889: [Enum] fix multiple-inheritance regression (GH-22487) (GH-23672)
(cherry picked from commit c266736)
1 parent b6d6f53 commit 699e5e4

3 files changed

Lines changed: 35 additions & 3 deletions

File tree

Lib/enum.py

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

151152
# save enum items into separate mapping so they don't get baked into
152153
# the new class
@@ -506,12 +507,16 @@ def _find_data_type(bases):
506507
for base in chain.__mro__:
507508
if base is object:
508509
continue
510+
elif issubclass(base, Enum):
511+
if base._member_type_ is not object:
512+
data_types.append(base._member_type_)
513+
break
509514
elif '__new__' in base.__dict__:
510515
if issubclass(base, Enum):
511516
continue
512517
data_types.append(candidate or base)
513518
break
514-
elif not issubclass(base, Enum):
519+
else:
515520
candidate = base
516521
if len(data_types) > 1:
517522
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
@@ -2000,6 +2000,32 @@ class Decision2(MyEnum):
20002000
REVERT_ALL = "REVERT_ALL"
20012001
RETRY = "RETRY"
20022002

2003+
def test_multiple_mixin_inherited(self):
2004+
class MyInt(int):
2005+
def __new__(cls, value):
2006+
return super().__new__(cls, value)
2007+
2008+
class HexMixin:
2009+
def __repr__(self):
2010+
return hex(self)
2011+
2012+
class MyIntEnum(HexMixin, MyInt, enum.Enum):
2013+
pass
2014+
2015+
class Foo(MyIntEnum):
2016+
TEST = 1
2017+
self.assertTrue(isinstance(Foo.TEST, MyInt))
2018+
self.assertEqual(repr(Foo.TEST), "0x1")
2019+
2020+
class Fee(MyIntEnum):
2021+
TEST = 1
2022+
def __new__(cls, value):
2023+
value += 1
2024+
member = int.__new__(cls, value)
2025+
member._value_ = value
2026+
return member
2027+
self.assertEqual(Fee.TEST, 2)
2028+
20032029
def test_empty_globals(self):
20042030
# bpo-35717: sys._getframe(2).f_globals['__name__'] fails with KeyError
20052031
# 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)