Python3.11 introduced StrEnum and IntEnum which inherit str or int respectively, and also inherit ReprEnum, which in turn inherits Enum.
ReprEnum's implementation is actually empty.
>>> print(inspect.getsource(ReprEnum))
class ReprEnum(Enum):
"""
Only changes the repr(), leaving str() and format() to the mixed-in type.
"""
If I create a StrEnum and check the MRO, I can see that str comes first.
class Strings(StrEnum):
A = "a"
>>> Strings.__mro__
(<enum 'Strings'>, <enum 'StrEnum'>, <class 'str'>, <enum 'ReprEnum'>, <enum 'Enum'>, <class 'object'>)
Both str and Enum define a __str__ and a __repr__
>>> str.__repr__
<slot wrapper '__repr__' of 'str' objects>
>>> str.__str__
<slot wrapper '__str__' of 'str' objects>
>>> Enum.__repr__
<function Enum.__repr__ at 0x7ffff69f72e0>
>>> Enum.__str__
<function Enum.__str__ at 0x7ffff69f7380>
How then does __repr__ get inherited from Enum and __str__ get inherited from str?
The
__repr__method comes the normal way, inherited fromEnum(viaStrEnum)For the
__str__method, the metaclassEnumTypechecks for the presence ofReprEnumand "hoists up" thestrandformathandling of the mixed-in data type into the class namespace at class definition time here:Now that a
Strings.__str__method may be found directly in the class namespace, the MRO needn't be traversed.