Search code examples
pythonstringenumsstring-formattingrepr

Formatted Python string uses neither repr nor str - what is happening?


I have an enumeration ResourceType that inherits from both namedtuple and Enum, and I don't override __str__ or __repr__ anywhere. When I format an instance of that enum I unexpectedly get just the undecorated value, as opposed to either the repr() or the str(). How is this possible? What is being called?

Enum details (simplified):

from enum import Enum, auto
from collections import namedtuple

class ResourceType(namedtuple('ResourceType', 'value ext required'), Enum):
    RGB = auto(), '.png', True

Output:

>>> repr(ResourceType.RGB)
"<ResourceType.RGB: ResourceType(value=<enum.auto object at 0x7f44b7d48d30>, ext='.png', required=True)>"

>>> str(ResourceType.RGB)
'ResourceType.RGB'

>>> f"{ResourceType.RGB}"
"ResourceType(value=<enum.auto object at 0x7f44b7d48d30>, ext='.png', required=True)"

The last value is neither the repr() nor the str(), so even if namedtuple is providing that string, why does it not also provide the str/repr?


Solution

  • When you insert an object into an f-string in this way it calls the __format__ method.

    from enum import Enum, auto
    from collections import namedtuple
    
    class ResourceType(namedtuple('ResourceType', 'value ext required'), Enum):
        RGB = auto(), '.png', True
    
        def __repr__(self):
            return "REPR"
    
        def __str__(self):
            return "STR"
    
        def __format__(self, format_spec):
            return "FORMAT"
    
    print(repr(ResourceType.RGB))
    print(str(ResourceType.RGB))
    print(f"{ResourceType.RGB}")
    

    gives output of

    REPR
    STR
    FORMAT