mirror of
https://github.com/python/cpython.git
synced 2024-11-23 18:04:37 +08:00
bpo-39587: Enum - use correct mixed-in data type (GH-22263)
This commit is contained in:
parent
2e87774df1
commit
bff01f3a3a
13
Lib/enum.py
13
Lib/enum.py
@ -482,14 +482,25 @@ class EnumMeta(type):
|
|||||||
return object, Enum
|
return object, Enum
|
||||||
|
|
||||||
def _find_data_type(bases):
|
def _find_data_type(bases):
|
||||||
|
data_types = []
|
||||||
for chain in bases:
|
for chain in bases:
|
||||||
|
candidate = None
|
||||||
for base in chain.__mro__:
|
for base in chain.__mro__:
|
||||||
if base is object:
|
if base is object:
|
||||||
continue
|
continue
|
||||||
elif '__new__' in base.__dict__:
|
elif '__new__' in base.__dict__:
|
||||||
if issubclass(base, Enum):
|
if issubclass(base, Enum):
|
||||||
continue
|
continue
|
||||||
return base
|
data_types.append(candidate or base)
|
||||||
|
break
|
||||||
|
elif not issubclass(base, Enum):
|
||||||
|
candidate = base
|
||||||
|
if len(data_types) > 1:
|
||||||
|
raise TypeError('too many data types: %r' % data_types)
|
||||||
|
elif data_types:
|
||||||
|
return data_types[0]
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
# ensure final parent class is an Enum derivative, find any concrete
|
# ensure final parent class is an Enum derivative, find any concrete
|
||||||
# data type, and check that Enum has no members
|
# data type, and check that Enum has no members
|
||||||
|
@ -560,6 +560,49 @@ class TestEnum(unittest.TestCase):
|
|||||||
self.assertFormatIsValue('{:>20}', Directional.WEST)
|
self.assertFormatIsValue('{:>20}', Directional.WEST)
|
||||||
self.assertFormatIsValue('{:<20}', Directional.WEST)
|
self.assertFormatIsValue('{:<20}', Directional.WEST)
|
||||||
|
|
||||||
|
def test_enum_str_override(self):
|
||||||
|
class MyStrEnum(Enum):
|
||||||
|
def __str__(self):
|
||||||
|
return 'MyStr'
|
||||||
|
class MyMethodEnum(Enum):
|
||||||
|
def hello(self):
|
||||||
|
return 'Hello! My name is %s' % self.name
|
||||||
|
class Test1Enum(MyMethodEnum, int, MyStrEnum):
|
||||||
|
One = 1
|
||||||
|
Two = 2
|
||||||
|
self.assertEqual(str(Test1Enum.One), 'MyStr')
|
||||||
|
#
|
||||||
|
class Test2Enum(MyStrEnum, MyMethodEnum):
|
||||||
|
One = 1
|
||||||
|
Two = 2
|
||||||
|
self.assertEqual(str(Test2Enum.One), 'MyStr')
|
||||||
|
|
||||||
|
def test_inherited_data_type(self):
|
||||||
|
class HexInt(int):
|
||||||
|
def __repr__(self):
|
||||||
|
return hex(self)
|
||||||
|
class MyEnum(HexInt, enum.Enum):
|
||||||
|
A = 1
|
||||||
|
B = 2
|
||||||
|
C = 3
|
||||||
|
self.assertEqual(repr(MyEnum.A), '<MyEnum.A: 0x1>')
|
||||||
|
|
||||||
|
def test_too_many_data_types(self):
|
||||||
|
with self.assertRaisesRegex(TypeError, 'too many data types'):
|
||||||
|
class Huh(str, int, Enum):
|
||||||
|
One = 1
|
||||||
|
|
||||||
|
class MyStr(str):
|
||||||
|
def hello(self):
|
||||||
|
return 'hello, %s' % self
|
||||||
|
class MyInt(int):
|
||||||
|
def repr(self):
|
||||||
|
return hex(self)
|
||||||
|
with self.assertRaisesRegex(TypeError, 'too many data types'):
|
||||||
|
class Huh(MyStr, MyInt, Enum):
|
||||||
|
One = 1
|
||||||
|
|
||||||
|
|
||||||
def test_hash(self):
|
def test_hash(self):
|
||||||
Season = self.Season
|
Season = self.Season
|
||||||
dates = {}
|
dates = {}
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
use the correct mix-in data type when constructing Enums
|
Loading…
Reference in New Issue
Block a user