The f-string grammar clearly specifies the correct order of f-string =, !, and : specifiers:
replacement_field ::= "{" f_expression ["="] ["!" conversion] [":" format_spec] "}"
However, when these components are used in the wrong order, the error messages, while understandable if you know the grammar, are not exactly helpful for users of all knowledge levels.
>>> foo = 12.345
>>> f'{foo=:.2f}' # correct ordering of = and :
'foo=12.35'
>>> f'{foo:.2f=}' # incorrect ordering of : and =
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: Invalid format specifier
>>> f'{foo=!r}' # correct ordering of = and !
'foo=12.345'
>>> f'{foo!r=}' # incorrect ordering of ! and =
File "<stdin>", line 1
SyntaxError: f-string: expecting '}'
>>> bar = 'abcd'
>>> f'{bar!r:.2s}' # correct ordering of ! and :
"'a"
>>> f'{bar:.2s!r}' # incorrect ordering of : and !
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: Invalid format specifier
It would be more helpful to have more descriptive error messages specifying the correct order of these features. f-string format specifiers, especially ! and =, are in my experience fairly poorly known features, and more descriptive feedback when they are used incorrectly would avoid discouraging users from using them at all upon encountering a cryptic error.
Since __format__ can have an arbitrary implementation for different data types, and therefore there might be some user-defined class that accepts :.2f!r as a valid format specifier, the ValueErrors here might have to stay, but at least the SyntaxError from f'{foo!r=}' could be clearer.
|