Skip to content

Commit b278344

Browse files
ethanfurmanSeth Sims
authored and
Seth Sims
committed
bpo-41816: StrEnum.__str__ is str.__str__ (pythonGH-22362)
use `str.__str__` for `StrEnum` so that `str(StrEnum.member)` is the same as directly accessing the string value of the `StrEnum` member
1 parent cdeddcb commit b278344

File tree

3 files changed

+48
-0
lines changed

3 files changed

+48
-0
lines changed

Doc/library/enum.rst

+15
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,11 @@ an incorrect member::
622622
Before :class:`StrEnum`, ``Directions.NORTH`` would have been the :class:`tuple`
623623
``('north',)``.
624624

625+
.. note::
626+
627+
Unlike other Enum's, ``str(StrEnum.member)`` will return the value of the
628+
member instead of the usual ``"EnumClass.member"``.
629+
625630
.. versionadded:: 3.10
626631

627632

@@ -1243,3 +1248,13 @@ all named flags and all named combinations of flags that are in the value::
12431248
>>> Color(7) # not named combination
12441249
<Color.CYAN|MAGENTA|BLUE|YELLOW|GREEN|RED: 7>
12451250

1251+
``StrEnum`` and :meth:`str.__str__`
1252+
"""""""""""""""""""""""""""""""""""
1253+
1254+
An important difference between :class:`StrEnum` and other Enums is the
1255+
:meth:`__str__` method; because :class:`StrEnum` members are strings, some
1256+
parts of Python will read the string data directly, while others will call
1257+
:meth:`str()`. To make those two operations have the same result,
1258+
:meth:`StrEnum.__str__` will be the same as :meth:`str.__str__` so that
1259+
``str(StrEnum.member) == StrEnum.member`` is true.
1260+

Lib/enum.py

+2
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,8 @@ def __new__(cls, *values):
718718
member._value_ = value
719719
return member
720720

721+
__str__ = str.__str__
722+
721723

722724
def _reduce_ex_by_name(self, proto):
723725
return self.name

Lib/test/test_enum.py

+31
Original file line numberDiff line numberDiff line change
@@ -2036,6 +2036,37 @@ class GoodStrEnum(StrEnum):
20362036
two = '2'
20372037
three = b'3', 'ascii'
20382038
four = b'4', 'latin1', 'strict'
2039+
self.assertEqual(GoodStrEnum.one, '1')
2040+
self.assertEqual(str(GoodStrEnum.one), '1')
2041+
self.assertEqual(GoodStrEnum.one, str(GoodStrEnum.one))
2042+
self.assertEqual(GoodStrEnum.one, '{}'.format(GoodStrEnum.one))
2043+
#
2044+
class DumbMixin:
2045+
def __str__(self):
2046+
return "don't do this"
2047+
class DumbStrEnum(DumbMixin, StrEnum):
2048+
five = '5'
2049+
six = '6'
2050+
seven = '7'
2051+
self.assertEqual(DumbStrEnum.seven, '7')
2052+
self.assertEqual(str(DumbStrEnum.seven), "don't do this")
2053+
#
2054+
class EnumMixin(Enum):
2055+
def hello(self):
2056+
print('hello from %s' % (self, ))
2057+
class HelloEnum(EnumMixin, StrEnum):
2058+
eight = '8'
2059+
self.assertEqual(HelloEnum.eight, '8')
2060+
self.assertEqual(HelloEnum.eight, str(HelloEnum.eight))
2061+
#
2062+
class GoodbyeMixin:
2063+
def goodbye(self):
2064+
print('%s wishes you a fond farewell')
2065+
class GoodbyeEnum(GoodbyeMixin, EnumMixin, StrEnum):
2066+
nine = '9'
2067+
self.assertEqual(GoodbyeEnum.nine, '9')
2068+
self.assertEqual(GoodbyeEnum.nine, str(GoodbyeEnum.nine))
2069+
#
20392070
with self.assertRaisesRegex(TypeError, '1 is not a string'):
20402071
class FirstFailedStrEnum(StrEnum):
20412072
one = 1

0 commit comments

Comments
 (0)