classification
Title: IntEnum __format__ behavior can't be overridden through __str__
Type: behavior Stage: resolved
Components: Library (Lib) Versions: Python 3.9, Python 3.8
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: ethan.furman Nosy List: eric.smith, ethan.furman, jason.curtis
Priority: normal Keywords: patch

Created on 2019-07-01 23:24 by jason.curtis, last changed 2020-09-13 20:51 by ethan.furman. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 14545 merged python-dev, 2019-07-02 05:42
PR 22227 merged ethan.furman, 2020-09-13 20:20
PR 22228 closed ethan.furman, 2020-09-13 20:24
Messages (7)
msg347089 - (view) Author: Jason Curtis (jason.curtis) * Date: 2019-07-01 23:24
Combining int and Enum, as with enum.IntEnum results in a class where __str__ cannot be effectively overridden. For example:


from enum import IntEnum

class myIntEnum(IntEnum):
    x = 1
    
    def __str__(self):
        return 'aaaaAAAa'
    
f'{myIntEnum.x}, {str(myIntEnum.x)}'


Expected output:
'aaaaAAAa, aaaaAAAa'

Actual output:
'1, aaaaAAAa'

Overriding __str__ in this way works as expected if the inherited classes are int or Enum individually. However, it does not work when inheriting (int, Enum) or when inheriting (intEnum).

Presumably this is a side effect of Enum's mixin behavior documented at https://docs.python.org/3/library/enum.html#others and it is possibly related to https://bugs.python.org/issue18264 .
msg347090 - (view) Author: Jason Curtis (jason.curtis) * Date: 2019-07-01 23:26
I mistyped - __str__ can be overridden effectively, but __format__ has to be overridden instead or overridden also to get the desired f-string behavior.
msg347094 - (view) Author: Jason Curtis (jason.curtis) * Date: 2019-07-01 23:43
related cPython code: https://github.com/python/cpython/blob/19a1e1eb86115db66c1faae5927f87e3a12692fc/Lib/enum.py#L626

If we're in a mixed-in class but the class has overridden __str__(), we should probably use str(self) instead of self._value_.
msg347096 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2019-07-02 00:38
Note that this isn't really related to f-strings, except that they use the __format__ protocol, as does str.__format__.

>>> format(myIntEnum.x)
'1'
msg347291 - (view) Author: Ethan Furman (ethan.furman) * (Python committer) Date: 2019-07-04 18:29
New changeset 2f19e82fbe98ce86bcd98a176328af2808b678e8 by Ethan Furman (thatneat) in branch 'master':
bpo-37479: on Enum subclasses with mixins, __format__ uses overridden __str__ (GH-14545)
https://github.com/python/cpython/commit/2f19e82fbe98ce86bcd98a176328af2808b678e8
msg376848 - (view) Author: Ethan Furman (ethan.furman) * (Python committer) Date: 2020-09-13 20:47
New changeset 38c8d3930eb872258a82339bcba3bce1d0e3ac2c by Ethan Furman in branch '3.8':
[3.8] bpo-37479: Enum - use correct __format__ (GH-14545)
https://github.com/python/cpython/commit/38c8d3930eb872258a82339bcba3bce1d0e3ac2c
msg376851 - (view) Author: Ethan Furman (ethan.furman) * (Python committer) Date: 2020-09-13 20:51
Thank you, Jason!
History
Date User Action Args
2020-09-13 20:51:07ethan.furmansetstatus: open -> closed
versions: + Python 3.8, Python 3.9, - Python 3.6
messages: + msg376851

resolution: fixed
stage: patch review -> resolved
2020-09-13 20:47:53ethan.furmansetmessages: + msg376848
2020-09-13 20:24:58ethan.furmansetpull_requests: + pull_request21283
2020-09-13 20:20:12ethan.furmansetpull_requests: + pull_request21282
2019-07-04 18:29:02ethan.furmansetmessages: + msg347291
2019-07-02 05:51:34jason.curtissettitle: IntEnum f-string behavior can't be overridden -> IntEnum __format__ behavior can't be overridden through __str__
2019-07-02 05:42:03python-devsetkeywords: + patch
stage: patch review
pull_requests: + pull_request14358
2019-07-02 01:19:41ethan.furmansetassignee: ethan.furman

nosy: + ethan.furman
2019-07-02 00:38:41eric.smithsetnosy: + eric.smith
messages: + msg347096
2019-07-01 23:43:05jason.curtissetmessages: + msg347094
2019-07-01 23:26:59jason.curtissetmessages: + msg347090
2019-07-01 23:24:11jason.curtiscreate