Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions Doc/library/enum.rst
Original file line number Diff line number Diff line change
Expand Up @@ -739,9 +739,11 @@ Some rules:
:meth:`__str__` and :meth:`__repr__` respectively; other codes (such as
`%i` or `%h` for IntEnum) treat the enum member as its mixed-in type.
5. :ref:`Formatted string literals <f-strings>`, :meth:`str.format`,
and :func:`format` will use the mixed-in
type's :meth:`__format__`. If the :class:`Enum` class's :func:`str` or
:func:`repr` is desired, use the `!s` or `!r` format codes.
and :func:`format` will use the mixed-in type's :meth:`__format__`
unless :meth:`__str__` or :meth:`__format__` is overridden in the subclass,
In which case the overridden methods or :class:`Enum` methods will be used.
If the :class:`Enum` class's :func:`str` or :func:`repr` is desired, use the
`!s` or `!r` format codes.

When to use :meth:`__new__` vs. :meth:`__init__`
------------------------------------------------
Expand Down
5 changes: 3 additions & 2 deletions Lib/enum.py
Original file line number Diff line number Diff line change
Expand Up @@ -622,8 +622,9 @@ def __format__(self, format_spec):
# we can get strange results with the Enum name showing up instead of
# the value

# pure Enum branch
if self._member_type_ is object:
# pure Enum branch, or branch with __str__ explicitly overridden
str_overridden = type(self).__str__ != Enum.__str__
if self._member_type_ is object or str_overridden:
cls = str
val = str(self)
# mix-in branch
Expand Down
53 changes: 52 additions & 1 deletion Lib/test/test_enum.py
Original file line number Diff line number Diff line change
Expand Up @@ -445,12 +445,63 @@ def test_format_enum(self):
self.assertEqual('{:<20}'.format(Season.SPRING),
'{:<20}'.format(str(Season.SPRING)))

def test_format_enum_custom(self):
def test_str_override_enum(self):
class EnumWithStrOverrides(Enum):
one = auto()
two = auto()

def __str__(self):
return 'Str!'
self.assertEqual(str(EnumWithStrOverrides.one), 'Str!')
self.assertEqual('{}'.format(EnumWithStrOverrides.one), 'Str!')

def test_format_override_enum(self):
class EnumWithFormatOverride(float, Enum):
one = 1.0
two = 2.0
def __format__(self, spec):
return 'Format!!'
self.assertEqual(str(EnumWithFormatOverride.one), 'EnumWithFormatOverride.one')
self.assertEqual('{}'.format(EnumWithFormatOverride.one), 'Format!!')

def test_str_and_format_override_enum(self):
class EnumWithStrFormatOverrides(Enum):
one = auto()
two = auto()
def __str__(self):
return 'Str!'
def __format__(self, spec):
return 'Format!'
self.assertEqual(str(EnumWithStrFormatOverrides.one), 'Str!')
self.assertEqual('{}'.format(EnumWithStrFormatOverrides.one), 'Format!')

def test_str_override_mixin(self):
class MixinEnumWithStrOverride(float, Enum):
one = 1.0
two = 2.0
def __str__(self):
return 'Overridden!'
self.assertEqual(str(MixinEnumWithStrOverride.one), 'Overridden!')
self.assertEqual('{}'.format(MixinEnumWithStrOverride.one), 'Overridden!')

def test_str_and_format_override_mixin(self):
class MixinWithStrFormatOverrides(float, Enum):
one = 1.0
two = 2.0
def __str__(self):
return 'Str!'
def __format__(self, spec):
return 'Format!'
self.assertEqual(str(MixinWithStrFormatOverrides.one), 'Str!')
self.assertEqual('{}'.format(MixinWithStrFormatOverrides.one), 'Format!')

def test_format_override_mixin(self):
class TestFloat(float, Enum):
one = 1.0
two = 2.0
def __format__(self, spec):
return 'TestFloat success!'
self.assertEqual(str(TestFloat.one), 'TestFloat.one')
self.assertEqual('{}'.format(TestFloat.one), 'TestFloat success!')

def assertFormatIsValue(self, spec, member):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
When `Enum.__str__` is overridden in a derived class, the override will be
used by `Enum.__format__` regardless of whether mixin classes are present.