Removed unneeded footnotes referencing other PEPs. Cleaned up some language. Fixed up some formatting errors.

This commit is contained in:
Eric V. Smith 2015-09-04 21:25:59 -04:00
parent c865de6aa8
commit 581f95229f
1 changed files with 38 additions and 42 deletions

View File

@ -28,7 +28,7 @@ string formatting mechanisms.
f-strings provide a way to embed expressions inside string literals,
using a minimal syntax. It should be noted that an f-string is really
an expression evaluated at run time, not a constant value. In Python
source code, an f-string is a literal string, prefixed with 'f', that
source code, an f-string is a literal string, prefixed with 'f', which
contains expressions inside braces. The expressions are replaced with
their values. Some examples are::
@ -41,10 +41,10 @@ their values. Some examples are::
>>> f'He said his name is {name!r}.'
"He said his name is 'Fred'."
A similar feature was proposed in PEP 215 [#]_. PEP 215 proposed to
support a subset of Python expressions, and did not support the
type-specific string formatting (the ``__format__()`` method) which
was introduced with PEP 3101 [#]_.
A similar feature was proposed in PEP 215. PEP 215 proposed to support
a subset of Python expressions, and did not support the type-specific
string formatting (the ``__format__()`` method) which was introduced
with PEP 3101.
Rationale
=========
@ -79,7 +79,7 @@ To be defensive, the following code should be used::
%-formatting. In particular, it uses normal function call syntax (and
therefor supports multiple parameters) and it is extensible through
the ``__format__()`` method on the object being converted to a
string. See PEP-3101 for a detailed rationale. This PEP reuses much of
string. See PEP 3101 for a detailed rationale. This PEP reuses much of
the ``str.format()`` syntax and machinery, in order to provide
continuity with an existing Python string formatting mechanism.
@ -90,9 +90,9 @@ is its verbosity. For example, the text ``value`` is repeated here::
>>> 'The value is {value}.'.format(value=value)
'The value is 80.'
Even in its simplest form, there is a bit of boilerplate, and the
value that's inserted into the placeholder is sometimes far removed
from where the placeholder is situated::
Even in its simplest form there is a bit of boilerplate, and the value
that's inserted into the placeholder is sometimes far removed from
where the placeholder is situated::
>>> 'The value is {}.'.format(value)
'The value is 80.'
@ -170,34 +170,35 @@ Specification
In source code, f-strings are string literals that are prefixed by the
letter 'f'. 'f' may be combined with 'r', in either order, to produce
raw f-string literals. 'f' may not be combined with 'b': there are no
binary f-strings. 'f' may also be combined with 'u', in either order,
although adding 'u' has no effect.
raw f-string literals. 'f' may not be combined with 'b': this PEP does
not propose to add binary f-strings. 'f' may also be combined with
'u', in either order, although adding 'u' has no effect.
f-strings are tokenized using the same rules as normal strings, raw
strings, binary strings, and triple quoted strings. That is, the
string must end with the same character that it started with: if it
starts with a single quote it must end with a single quote, etc. 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).
When tokenizing source files, f-strings use the same rules as normal
strings, raw strings, binary strings, and triple quoted strings. That
is, the string must end with the same character that it started with:
if it starts with a single quote it must end with a single quote, etc.
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 [#]_.
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 then 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 braces '{{' or '}}'
are replaced by the corresponding single brace. Doubled opening braces
do not signify the start of an expression.
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
braces ``'{{'`` or ``'}}'`` are replaced by the corresponding single
brace. Doubled opening braces do not signify the start of an
expression.
Following the expression, an optional type conversion may be
specified. The allowed conversions are ``'!s'``, ``'!r'``, or
@ -344,7 +345,7 @@ yields the value::
While the exact method of this run time concatenation is unspecified,
the above code might evaluate to::
'ab' + x.__format__('') + '{c}' + 'str<', y.__format__('^4') + 'de'
'ab' + x.__format__('') + '{c}' + 'str<' + y.__format__('^4') + 'de'
Error handling
--------------
@ -463,8 +464,8 @@ of uses of ``string.Template``, but hundreds of uses of
``str.format()``.
Another proposed alternative was to have the substituted text between
``\\{`` and ``}`` or between ``\\{`` and ``\\}``. While this syntax
would probably be desirable if all string literals were to support
``\{`` and ``}`` or between ``\{`` and ``\}``. While this syntax would
probably be desirable if all string literals were to support
interpolation, this PEP only supports strings that are already marked
with the leading ``'f'``. As such, the PEP is using unadorned braces
to denoted substituted text, in order to leverage end user familiarity
@ -493,7 +494,7 @@ While it's true that very ugly expressions could be included in the
f-strings, this PEP takes the position that such uses should be
addressed in a linter or code review::
>>> f'mapping is { {a:b for (a, b) in ((1, 2), (3, 4))}}'
>>> f'mapping is { {a:b for (a, b) in ((1, 2), (3, 4))} }'
'mapping is {1: 2, 3: 4}'
Similar support in other languages
@ -548,8 +549,9 @@ Triple-quoted f-strings
-----------------------
Triple quoted f-strings are allowed. These strings are parsed just as
normal triple-quoted strings are. After parsing, the normal f-string
logic is applied, and ``__format__()`` on each value is called.
normal triple-quoted strings are. After parsing and decoding, the
normal f-string logic is applied, and ``__format__()`` on each value
is called.
Raw f-strings
-------------
@ -665,12 +667,6 @@ References
.. [#] string.Template documentation
(https://docs.python.org/3/library/string.html#template-strings)
.. [#] PEP 215: String Interpolation
(https://www.python.org/dev/peps/pep-0215/)
.. [#] PEP 3101: Advanced String Formatting
(https://www.python.org/dev/peps/pep-3101/)
.. [#] Formatting using locals() and globals()
(https://mail.python.org/pipermail/python-ideas/2015-July/034671.html)