Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

f-string format specifier with None throws TypeError

Using plain f-strings with a NoneType object works:

>>> a = None
>>> f'{a}'
'None'

However, when using a format specifier, it breaks---as does str.format():

>>> f'{a:>6}'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported format string passed to NoneType.__format__

>>> '{:>6}'.format(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported format string passed to NoneType.__format__

Unexpectedly, (for me, at least) the old C-style string formatting works:

>>> '%10s' % a
'      None'

What is going on here? I don't understand why f'{a:>6}' doesn't evaluate to ' None'. Why should a format specifier break it?

Is this a bug in python? If it is a bug, how would I fix it?

like image 373
reynoldsnlp Avatar asked Jun 10 '26 09:06

reynoldsnlp


2 Answers

None is not a string, so f'{None:>6}' makes no sense. You can convert it to a string with f'{None!s:>6}'. !a, !s, and !r call ascii(), str(), and repr() respectively on an object.

like image 95
Mark Tolonen Avatar answered Jun 11 '26 22:06

Mark Tolonen


None doesn't support format specifiers. It's up to each object type to determine how it wants to handle format specifiers, and the default is to reject them:

The __format__ method of object itself raises a TypeError if passed any non-empty string.

None inherits this default.

You seem to be expecting None to handle format specifiers the same way strings do, where '{:>6}'.format('None') == ' None'. It kind of sounds like you expect all types to handle format specifiers the way strings do, or you expect the string behavior to be the default. The way strings handle format specifiers is specific to strings; other types have their own handling.


You might be thinking, hey, why doesn't %10s fail too? First, the s requests that the argument be converted to a string by str before any further processing. Second, all conversion specifier handling in printf-style string formatting is performed by str.__mod__; it never delegates to the arguments to figure out what a conversion specifier means.

like image 33
user2357112 supports Monica Avatar answered Jun 11 '26 21:06

user2357112 supports Monica