Disallow backslashes in the expression part of f-strings. See https://mail.python.org/pipermail/python-dev/2016-September/146357.html for a discussion and an implied acceptance by Guido.
This commit is contained in:
parent
b60019e09a
commit
ac0afc6434
79
pep-0498.txt
79
pep-0498.txt
|
@ -171,9 +171,9 @@ Specification
|
|||
|
||||
In source code, f-strings are string literals that are prefixed by the
|
||||
letter 'f' or 'F'. Everywhere this PEP uses 'f', 'F' may also be
|
||||
used. 'f' may be combined with 'r', in either order, to produce raw
|
||||
f-string literals. 'f' may not be combined with 'b': this PEP does not
|
||||
propose to add binary f-strings. 'f' may not be combined with 'u'.
|
||||
used. 'f' may be combined with 'r' or 'R', in either order, to produce
|
||||
raw f-string literals. 'f' may not be combined with 'b': this PEP does
|
||||
not propose to add binary f-strings. 'f' may not be combined with 'u'.
|
||||
|
||||
When tokenizing source files, f-strings use the same rules as normal
|
||||
strings, raw strings, binary strings, and triple quoted strings. That
|
||||
|
@ -183,33 +183,24 @@ This implies that any code that currently scans Python code looking
|
|||
for strings should be trivially modifiable to recognize f-strings
|
||||
(parsing within an f-string is another matter, of course).
|
||||
|
||||
Once tokenized, f-strings are decoded. This will convert backslash
|
||||
escapes such as ``'\n'``, ``'\"'``, ``"\'"``, ``'\xhh'``,
|
||||
``'\uxxxx'``, ``'\Uxxxxxxxx'``, and named unicode characters
|
||||
``'\N{name}'`` into their associated Unicode characters [#]_.
|
||||
|
||||
Up to this point, the processing of f-strings and normal strings is
|
||||
exactly the same.
|
||||
|
||||
The difference is that f-strings are further parsed in to literals and
|
||||
expressions. Expressions appear within curly braces ``'{'`` and
|
||||
``'}'``. The parts of the string outside of braces are literals. The
|
||||
expressions are evaluated, formatted with the existing __format__
|
||||
protocol, then the results are concatenated together with the string
|
||||
literals. While scanning the string for expressions, any doubled
|
||||
Once tokenized, f-strings are parsed in to literal strings and
|
||||
expressions. Expressions appear within curly braces ``'{'`` and
|
||||
``'}'``. While scanning the string for expressions, any doubled
|
||||
braces ``'{{'`` or ``'}}'`` inside literal portions of an f-string are
|
||||
replaced by the corresponding single brace. Doubled opening braces do
|
||||
replaced by the corresponding single brace. Doubled opening braces do
|
||||
not signify the start of an expression.
|
||||
|
||||
Note that ``__format__()`` is not called directly on each value. The
|
||||
actual code uses the equivalent of ``type(value).__format__(value,
|
||||
format_spec)``, or ``format(value, format_spec)``. See the
|
||||
documentation of the builtin ``format()`` function for more details.
|
||||
The parts of the f-string outside of braces are literal
|
||||
strings. These literal portions are then decoded. For non-raw
|
||||
f-strings, this includes converting backslash escapes such as
|
||||
``'\n'``, ``'\"'``, ``"\'"``, ``'\xhh'``, ``'\uxxxx'``,
|
||||
``'\Uxxxxxxxx'``, and named unicode characters ``'\N{name}'`` into
|
||||
their associated Unicode characters [#]_.
|
||||
|
||||
Comments, using the ``'#'`` character, are not allowed inside an
|
||||
expression.
|
||||
Backslashes may not appear anywhere within expressions. Comments,
|
||||
using the ``'#'`` character, are not allowed inside an expression.
|
||||
|
||||
Following the expression, an optional type conversion may be
|
||||
Following each expression, an optional type conversion may be
|
||||
specified. The allowed conversions are ``'!s'``, ``'!r'``, or
|
||||
``'!a'``. These are treated the same as in ``str.format()``: ``'!s'``
|
||||
calls ``str()`` on the expression, ``'!r'`` calls ``repr()`` on the
|
||||
|
@ -231,6 +222,11 @@ The expression is then formatted using the ``__format__`` protocol,
|
|||
using the format specifier as an argument. The resulting value is
|
||||
used when building the value of the f-string.
|
||||
|
||||
Note that ``__format__()`` is not called directly on each value. The
|
||||
actual code uses the equivalent of ``type(value).__format__(value,
|
||||
format_spec)``, or ``format(value, format_spec)``. See the
|
||||
documentation of the builtin ``format()`` function for more details.
|
||||
|
||||
Expressions cannot contain ``':'`` or ``'!'`` outside of strings or
|
||||
parentheses, brackets, or braces. The exception is that the ``'!='``
|
||||
operator is allowed as a special case.
|
||||
|
@ -238,21 +234,21 @@ operator is allowed as a special case.
|
|||
Escape sequences
|
||||
----------------
|
||||
|
||||
Scanning an f-string for expressions happens after escape sequences
|
||||
are decoded. Because ``hex(ord('{')) == 0x7b``, the f-string
|
||||
``f'\u007b4*10}'`` is decoded to ``f'{4*10}'``, which evaluates as
|
||||
the integer 40::
|
||||
Backslashes may not appear inside the expression portions of
|
||||
f-strings, so you cannot use them, for example, to escape quotes
|
||||
inside f-strings::
|
||||
|
||||
>>> f'\u007b4*10}'
|
||||
'40'
|
||||
>>> f'\x7b4*10}'
|
||||
'40'
|
||||
>>> f'\x7b4*10\N{RIGHT CURLY BRACKET}'
|
||||
'40'
|
||||
>>> f'{\'quoted string\'}'
|
||||
File "<stdin>", line 1
|
||||
SyntaxError: f-string expression part cannot include a backslash
|
||||
|
||||
These examples aren't generally useful, they're just to show that
|
||||
escape sequences are processed before f-strings are parsed for
|
||||
expressions.
|
||||
You can use a different type of quote inside the expression::
|
||||
|
||||
>>> f'{"quoted string"}'
|
||||
'quoted string'
|
||||
|
||||
Backslash escapes may appear inside the string portions of an
|
||||
f-string.
|
||||
|
||||
Note that the correct way to have a literal brace appear in the
|
||||
resulting string value is to double the brace::
|
||||
|
@ -272,11 +268,8 @@ 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. There are a number
|
||||
of correct ways to write this f-string: with escaped single quotes::
|
||||
|
||||
f'abc {a[\'x\']} def'
|
||||
|
||||
With a different quote character::
|
||||
of correct ways to write this f-string: with a different quote
|
||||
character::
|
||||
|
||||
f"abc {a['x']} def"
|
||||
|
||||
|
|
Loading…
Reference in New Issue