bpo-41889: [Enum] fix multiple-inheritance regression (GH-22487)

This commit is contained in:
Ethan Furman 2020-12-07 00:17:31 -08:00 committed by GitHub
parent 212337369a
commit c266736ec1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 35 additions and 3 deletions

View File

@ -146,8 +146,9 @@ class EnumMeta(type):
for key in ignore: for key in ignore:
classdict.pop(key, None) classdict.pop(key, None)
member_type, first_enum = metacls._get_mixins_(cls, bases) member_type, first_enum = metacls._get_mixins_(cls, bases)
__new__, save_new, use_args = metacls._find_new_(classdict, member_type, __new__, save_new, use_args = metacls._find_new_(
first_enum) classdict, member_type, first_enum,
)
# save enum items into separate mapping so they don't get baked into # save enum items into separate mapping so they don't get baked into
# the new class # the new class
@ -501,12 +502,16 @@ class EnumMeta(type):
for base in chain.__mro__: for base in chain.__mro__:
if base is object: if base is object:
continue continue
elif issubclass(base, Enum):
if base._member_type_ is not object:
data_types.append(base._member_type_)
break
elif '__new__' in base.__dict__: elif '__new__' in base.__dict__:
if issubclass(base, Enum): if issubclass(base, Enum):
continue continue
data_types.append(candidate or base) data_types.append(candidate or base)
break break
elif not issubclass(base, Enum): else:
candidate = base candidate = base
if len(data_types) > 1: if len(data_types) > 1:
raise TypeError('%r: too many data types: %r' % (class_name, data_types)) raise TypeError('%r: too many data types: %r' % (class_name, data_types))

View File

@ -2021,6 +2021,32 @@ class TestEnum(unittest.TestCase):
REVERT_ALL = "REVERT_ALL" REVERT_ALL = "REVERT_ALL"
RETRY = "RETRY" 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): def test_empty_globals(self):
# bpo-35717: sys._getframe(2).f_globals['__name__'] fails with KeyError # bpo-35717: sys._getframe(2).f_globals['__name__'] fails with KeyError
# when using compile and exec because f_globals is empty # when using compile and exec because f_globals is empty

View File

@ -0,0 +1 @@
Enum: fix regression involving inheriting a multiply-inherited enum