[issue18738] String formatting (% and str.format) issues with Enum

Eric V. Smith report at bugs.python.org
Mon Aug 19 14:45:38 CEST 2013


Eric V. Smith added the comment:

Oh, I don't feel my time has been wasted. Where else can I have a discussion of __format__?

With this patch, given this:

class UpperString(str):
  def __format__(self, fmt):
    return str.__format__(self, fmt).upper()

class UpperEnum(UpperString, Enum):
  pass

class S(UpperEnum):
  a = 'a'
  b = 'b'

this gives the (to me) surprising results of:

>>> format(S.a)
'S.a'
>>> format(S.a, '10')
'S.a       '
>>> format(S.a, '10s')
'A         '

I'd expect this to always use UpperString.__format__, since it understands all str format specs.

And before you say UpperString is contrived, I've used classes like it in the past: they're just like a string, but the __format__ method does something special after calling through to str.__format__. 

Which is why I think __format__ has to go in the derived type (IntEnum, in the originally reported case): only it can decide whether to call str.__format__ or the mix-in class's __format__.

Now, whether or not Enum needs to support such classes with specialized __format___, I can't say. I suppose it's not super-important. But it will be difficult to explain all of this.

Also, the patch give this:

>>> class E(IntEnum):
...   one = 1
...   two = 2
... 
>>> format(E.one)
'E.one'
>>> format(E.one, 's')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/eric/local/python/cpython/Lib/enum.py", line 463, in __format__
    return obj.__format__(val, format_spec)
ValueError: Unknown format code 's' for object of type 'int'

I can't format it using the 's' presentation type, despite the fact it looks like a string. I think you need to add 's' to your _remove_plain_format_chars.

And consider this valid (but arguably pathological) code:

>>> format(datetime.datetime.now(), '10')
'10'

Despite this being a valid datetime format spec, your code would consider it a str spec.

tl;dr: I think __format__ belongs in the class that understands how the subclass handles format specs.

----------

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue18738>
_______________________________________


More information about the Python-bugs-list mailing list