bpo-41889: [Enum] fix multiple-inheritance regression (GH-22487) (GH-23672)
(cherry picked from commit c266736ec1
)
This commit is contained in:
parent
b6d6f5367d
commit
699e5e4489
11
Lib/enum.py
11
Lib/enum.py
|
@ -145,8 +145,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
|
||||||
|
@ -506,12 +507,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))
|
||||||
|
|
|
@ -2000,6 +2000,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
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Enum: fix regression involving inheriting a multiply-inherited enum
|
Loading…
Reference in New Issue