PEP 498 introduced Literal String Interpolation (or “f-strings”).The expression portions of those literals however are subject tocertain restrictions. This PEP proposes a formal grammar liftingthose restrictions, promoting “f-strings” to “f expressions” or f-literals.
This PEP expands upon the f-strings introduced byPEP 498,so this text requires familiarity withPEP 498.
This PEP has been withdrawn in favour ofPEP 701.PEP 701 addresses all important points of this PEP.
This text will refer to the existing grammar as “f-strings”,and the proposed one as “f-literals”.
Furthermore, it will refer to the{}-delimited expressions inf-literals/f-strings as “expression portions” and the static string contentaround them as “string portions”.
The current implementation of f-strings in CPython relies on the existingstring parsing machinery and a post processing of its tokens. This results inseveral restrictions to the possible expressions usable within f-strings:
>>>f'Magic wand:{bag['wand']}' ^SyntaxError: invalid syntax
>>> f'Magic wand { bag[\'wand\'] } string'SyntaxError: f-string expression portion cannot include a backslash>>> f'''A complex trick: {... bag['bag'] # recursive bags!... }'''SyntaxError: f-string expression part cannot include '#'':' and'!' in braces:>>>f'Useless use of lambdas:{lambdax: x*2}'SyntaxError: unexpected EOF while parsing
These limitations serve no purpose from a language user perspective andcan be lifted by giving f-literals a regular grammar without exceptionsand implementing it using dedicated parse code.
The restrictions mentioned inMotivation are non-obvious and counter-intuitiveunless the user is familiar with the f-literals’ implementation details.
As mentioned, a previous version ofPEP 498 allowed escape sequencesanywhere in f-strings, including as ways to encode the braces delimitingthe expression portions and in their code. They would be expanded beforethe code is parsed, which would have had several important ramifications:
#. It would not be clear to human readers which portions are Expressionsand which are strings. Great material for an “obfuscated/underhandedPython challenge”#. Syntax highlighters are good in parsing nested grammar, but notin recognizing escape sequences. ECMAScript 2016 (JavaScript) allowsescape sequences in its identifiers[1] and the author knows of nosyntax highlighter able to correctly highlight code making use of this.
As a consequence, the expression portions would be harder to recognizewith and without the aid of syntax highlighting. With the new grammar,it is easy to extend syntax highlighters to correctly parseand display f-literals:
f'Magic wand:{bag['wand']:^10}'
Highlighting expression portions with possible escape sequences wouldmean to create a modified copy of all rules of the complete expressiongrammar, accounting for the possibility of escape sequences in key words,delimiters, and all other language syntax. One such duplication wouldyield one level of escaping depth and have to be repeated for a deeperescaping in a recursive f-literal. This is the case since no highlightingengine known to the author supports expanding escape sequences beforeapplying rules to a certain context. Nesting contexts however is astandard feature of all highlighting engines.
Familiarity also plays a role: Arbitrary nesting of expressionswithout expansion of escape sequences is available in every singleother language employing a string interpolation method that usesexpressions instead of just variable names.[2]
PEP 498 specified f-strings as the following, but places restrictions on it:
f' <text> { <expression> <optional !s, !r, or !a> <optional : format specifier> } <text> ... '
All restrictions mentioned in the PEP are lifted from f-literals,as explained below:
'#' character, are possible only in multi-linef-literals, since comments are terminated by the end of the line(which makes closing a single-line f-literal impossible).':' or'!' whereversyntactically valid. The first':' or'!' that is not partof an expression has to be followed a valid coercion or format specifier.A remaining restriction not explicitly mentioned byPEP 498 is line breaksin expression portions. Since strings delimited by single' or"characters are expected to be single line, line breaks remain illegalin expression portions of single line strings.
Note
Is lifting of the restrictions sufficient,or should we specify a more complete grammar?
f-literals are fully backwards compatible to f-strings,and expands the syntax considered legal.
TBD
IdentifierName specification(http://ecma-international.org/ecma-262/6.0/#sec-names-and-keywords )Yes,constcthulhu={H̹̙̦̮͉̩̗̗ͧ̇̏̊̾Eͨ͆͒̆ͮ̃͏̷̮̣̫̤̣Cͯ̂͐͏̨̛͔̦̟͈̻O̜͎͍͙͚̬̝̣̽ͮ͐͗̀ͤ̍̀͢M̴̡̲̭͍͇̼̟̯̦̉̒͠Ḛ̛̙̞̪̗ͥͤͩ̾͑̔͐ͅṮ̴̷̷̗̼͍̿̿̓̽͐H̙̙̔̄͜\u0042:42} is valid ECMAScript 2016
This document has been placed in the public domain.
Source:https://github.com/python/peps/blob/main/peps/pep-0536.rst
Last modified:2025-02-01 08:59:27 GMT