bpo-39587: Enum - use correct mixed-in data type (GH-22263)
(cherry picked from commit bff01f3a3a
)
Co-authored-by: Ethan Furman <ethan@stoneleaf.us>
This commit is contained in:
parent
5fdc142597
commit
8f8ebcca95
13
Lib/enum.py
13
Lib/enum.py
|
@ -487,14 +487,25 @@ class EnumMeta(type):
|
|||
return object, Enum
|
||||
|
||||
def _find_data_type(bases):
|
||||
data_types = []
|
||||
for chain in bases:
|
||||
candidate = None
|
||||
for base in chain.__mro__:
|
||||
if base is object:
|
||||
continue
|
||||
elif '__new__' in base.__dict__:
|
||||
if issubclass(base, Enum):
|
||||
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
|
||||
# data type, and check that Enum has no members
|
||||
|
|
|
@ -551,6 +551,49 @@ class TestEnum(unittest.TestCase):
|
|||
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):
|
||||
Season = self.Season
|
||||
dates = {}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
use the correct mix-in data type when constructing Enums
|
Loading…
Reference in New Issue