A colleague and I just stumbled across an interesting problem using an f-string. Here is a minimal example:
>>> f"{ 42:x}"
'2a'
Writing a space after the hexadecimal type leads to a ValueError
:
>>> f"{ 42:x }"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: Invalid format specifier
I understand the paragraph Leading and trailing whitespace in expressions is ignored in PEP 498 to mean that the space should actually be ignored.
Why does the space character lead to an error and what is the reasoning behind this?
CodePudding user response:
Per the link you shared:
For ease of readability, leading and trailing whitespace in expressions is ignored. This is a by-product of enclosing the expression in parentheses before evaluation.
The expression is everything[1] before the colon (:
), while the format specifier is everything afterwards.
{ 42 : x }
inside an f-string
is equivalent to ( 42 )
with a format specifier of " x "
.
( 42 ) == 42
but " x " != "x"
, and a format specifier is passed to the object's __format__
intact.
When the object attempts to format, it doesn't recognize the meaning of space (" "
) in those positions, and throws an error.
Furthermore, on some format specifiers, space actually has a meaning, for example as a fill character or as a sign option:
>>> f"{42: > 5}" # Width of 5, align to right, with space as fill and plus or minus as sign
' 42'
>>> f"{42:#> 5}" # Width of 5, align to right, with `#` as fill and space or minus as sign.
'## 42'
For more info, see the Format Specification Mini-Language.
1 Does not include the type conversion, for example !s
, !r
or !a
.