classification
Title: IntEnum __format__ behavior can't be overridden through __str__
Type: behavior Stage: patch review
Components: Library (Lib) Versions: Python 3.6
process
Status: open Resolution:
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 2019-07-04 18:29 by ethan.furman.

Pull Requests
URL Status Linked Edit
PR 14545 merged python-dev, 2019-07-02 05:42
Messages (5)
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
History
Date User Action Args
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