Reputation:
Why is f'{'one'}'
invalid syntax? Seems to me like if f-strings were sensible, as soon as a {
appears, everything inside of { ... }
should be considered Python code.
What's the reason the language designers decided to make the string's end quote be considered as a string end, even inside of { ... }
?
What advantages come from this?
Post-close edit
NOTE: This is an old question. From python 3.12 this is actually valid syntax. See: https://docs.python.org/3/whatsnew/3.12.html#whatsnew312-pep701
Upvotes: 6
Views: 4991
Reputation: 1084
Due to Python’s string tokenizing rules, the f-string
f'abc {a['x']} def'
is invalid. The tokenizer parses this as 3 tokens:f'abc {a['
,x
, and']} def'
. Just like regular strings, this cannot be fixed by using raw strings.
https://peps.python.org/pep-0498/#escape-sequences
Why didn't they "fix" the tokenizer to make it possible? Possibly backwards compatibility. Possibly it just isn't worth it when an easy fix is to simply mix "
inside '
for the common cases.
The reason the syntax acts like it does is that languages are built upon blocks (tokens) defined by a grammar that shows how tokens are built. Python's f-strings reused two existing building blocks. First, everything between the f'
and trailing '
are valid string contents. If you remove the f
, your Python program's syntax will still be correct (though the contents of the string will not be dynamic). Your example, '{'one'}'
fails this condition. The second condition is that the code between {
and }
is a valid Python expression. 'one'
is a valid, expression, but it must pass both conditions. The next alternative \'one\'
is a valid string literal but it's an invalid expression (cannot paste \'one\'
in the REPL, for example) - so it doesn't pass both conditions, either. Changing this would make f-strings take a different path through the parser and probably require duplicate code where it wasn't needed before. More detail on tokenization, grammars, and compiler design is beyond the scope of this short answer.
Upvotes: 7