[Python-checkins] cpython: Issue #25179: Documentation for formatted string literals aka f-strings

martin.panter python-checkins at python.org
Fri Feb 12 19:47:01 EST 2016


https://hg.python.org/cpython/rev/f4d7de7d18c0
changeset:   100233:f4d7de7d18c0
parent:      100230:37bacf3fa1f5
user:        Martin Panter <vadmium+py at gmail.com>
date:        Sat Feb 13 00:41:37 2016 +0000
summary:
  Issue #25179: Documentation for formatted string literals aka f-strings

Some of the inspiration and wording is taken from the text of PEP 498 by Eric
V. Smith, and the existing str.format() documentation.

files:
  Doc/faq/programming.rst            |    3 +-
  Doc/library/datetime.rst           |    9 +-
  Doc/library/enum.rst               |    3 +-
  Doc/library/stdtypes.rst           |   15 +-
  Doc/library/string.rst             |   10 +-
  Doc/reference/datamodel.rst        |    5 +-
  Doc/reference/lexical_analysis.rst |  108 ++++++++++++++++-
  Doc/tutorial/inputoutput.rst       |    3 +-
  Doc/tutorial/introduction.rst      |    3 +
  Doc/whatsnew/3.6.rst               |   20 ++-
  10 files changed, 158 insertions(+), 21 deletions(-)


diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst
--- a/Doc/faq/programming.rst
+++ b/Doc/faq/programming.rst
@@ -839,7 +839,8 @@
 To convert, e.g., the number 144 to the string '144', use the built-in type
 constructor :func:`str`.  If you want a hexadecimal or octal representation, use
 the built-in functions :func:`hex` or :func:`oct`.  For fancy formatting, see
-the :ref:`formatstrings` section, e.g. ``"{:04d}".format(144)`` yields
+the :ref:`f-strings` and :ref:`formatstrings` sections,
+e.g. ``"{:04d}".format(144)`` yields
 ``'0144'`` and ``"{:.3f}".format(1.0/3.0)`` yields ``'0.333'``.
 
 
diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst
--- a/Doc/library/datetime.rst
+++ b/Doc/library/datetime.rst
@@ -605,7 +605,8 @@
 .. method:: date.__format__(format)
 
    Same as :meth:`.date.strftime`. This makes it possible to specify a format
-   string for a :class:`.date` object when using :meth:`str.format`. For a
+   string for a :class:`.date` object in :ref:`formatted string
+   literals <f-strings>` and when using :meth:`str.format`. For a
    complete list of formatting directives, see
    :ref:`strftime-strptime-behavior`.
 
@@ -1180,7 +1181,8 @@
 .. method:: datetime.__format__(format)
 
    Same as :meth:`.datetime.strftime`.  This makes it possible to specify a format
-   string for a :class:`.datetime` object when using :meth:`str.format`.  For a
+   string for a :class:`.datetime` object in :ref:`formatted string
+   literals <f-strings>` and when using :meth:`str.format`.  For a
    complete list of formatting directives, see
    :ref:`strftime-strptime-behavior`.
 
@@ -1425,7 +1427,8 @@
 .. method:: time.__format__(format)
 
    Same as :meth:`.time.strftime`. This makes it possible to specify a format string
-   for a :class:`.time` object when using :meth:`str.format`.  For a
+   for a :class:`.time` object in :ref:`formatted string
+   literals <f-strings>` and when using :meth:`str.format`.  For a
    complete list of formatting directives, see
    :ref:`strftime-strptime-behavior`.
 
diff --git a/Doc/library/enum.rst b/Doc/library/enum.rst
--- a/Doc/library/enum.rst
+++ b/Doc/library/enum.rst
@@ -558,7 +558,8 @@
 4. %-style formatting:  `%s` and `%r` call the :class:`Enum` class's
    :meth:`__str__` and :meth:`__repr__` respectively; other codes (such as
    `%i` or `%h` for IntEnum) treat the enum member as its mixed-in type.
-5. :meth:`str.format` (or :func:`format`) will use the mixed-in
+5. :ref:`Formatted string literals <f-strings>`, :meth:`str.format`,
+   and :func:`format` will use the mixed-in
    type's :meth:`__format__`.  If the :class:`Enum` class's :func:`str` or
    :func:`repr` is desired, use the `!s` or `!r` format codes.
 
diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst
--- a/Doc/library/stdtypes.rst
+++ b/Doc/library/stdtypes.rst
@@ -1450,8 +1450,8 @@
 
    For more information on the ``str`` class and its methods, see
    :ref:`textseq` and the :ref:`string-methods` section below.  To output
-   formatted strings, see the :ref:`formatstrings` section.  In addition,
-   see the :ref:`stringservices` section.
+   formatted strings, see the :ref:`f-strings` and :ref:`formatstrings`
+   sections.  In addition, see the :ref:`stringservices` section.
 
 
 .. index::
@@ -2053,8 +2053,8 @@
 .. index::
    single: formatting, string (%)
    single: interpolation, string (%)
-   single: string; formatting
-   single: string; interpolation
+   single: string; formatting, printf
+   single: string; interpolation, printf
    single: printf-style formatting
    single: sprintf-style formatting
    single: % formatting
@@ -2064,9 +2064,10 @@
 
    The formatting operations described here exhibit a variety of quirks that
    lead to a number of common errors (such as failing to display tuples and
-   dictionaries correctly).  Using the newer :meth:`str.format` interface
-   helps avoid these errors, and also provides a generally more powerful,
-   flexible and extensible approach to formatting text.
+   dictionaries correctly).  Using the newer :ref:`formatted
+   string literals <f-strings>` or the :meth:`str.format` interface
+   helps avoid these errors.  These alternatives also provide more powerful,
+   flexible and extensible approaches to formatting text.
 
 String objects have one unique built-in operation: the ``%`` operator (modulo).
 This is also known as the string *formatting* or *interpolation* operator.
diff --git a/Doc/library/string.rst b/Doc/library/string.rst
--- a/Doc/library/string.rst
+++ b/Doc/library/string.rst
@@ -188,7 +188,9 @@
 
 The :meth:`str.format` method and the :class:`Formatter` class share the same
 syntax for format strings (although in the case of :class:`Formatter`,
-subclasses can define their own format string syntax).
+subclasses can define their own format string syntax).  The syntax is
+related to that of :ref:`formatted string literals <f-strings>`, but
+there are differences.
 
 Format strings contain "replacement fields" surrounded by curly braces ``{}``.
 Anything that is not contained in braces is considered literal text, which is
@@ -283,7 +285,8 @@
 
 "Format specifications" are used within replacement fields contained within a
 format string to define how individual values are presented (see
-:ref:`formatstrings`).  They can also be passed directly to the built-in
+:ref:`formatstrings` and :ref:`f-strings`).
+They can also be passed directly to the built-in
 :func:`format` function.  Each formattable type may define how the format
 specification is to be interpreted.
 
@@ -308,7 +311,8 @@
 If a valid *align* value is specified, it can be preceded by a *fill*
 character that can be any character and defaults to a space if omitted.
 It is not possible to use a literal curly brace ("``{``" or "``}``") as
-the *fill* character when using the :meth:`str.format`
+the *fill* character in a :ref:`formatted string literal
+<f-strings>` or when using the :meth:`str.format`
 method.  However, it is possible to insert a curly brace
 with a nested replacement field.  This limitation doesn't
 affect the :func:`format` function.
diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst
--- a/Doc/reference/datamodel.rst
+++ b/Doc/reference/datamodel.rst
@@ -1234,8 +1234,9 @@
 
 .. method:: object.__format__(self, format_spec)
 
-   Called by the :func:`format` built-in function (and by extension, the
-   :meth:`str.format` method of class :class:`str`) to produce a "formatted"
+   Called by the :func:`format` built-in function,
+   and by extension, evaluation of :ref:`formatted string literals
+   <f-strings>` and the :meth:`str.format` method, to produce a "formatted"
    string representation of an object. The ``format_spec`` argument is
    a string that contains a description of the formatting options desired.
    The interpretation of the ``format_spec`` argument is up to the type
diff --git a/Doc/reference/lexical_analysis.rst b/Doc/reference/lexical_analysis.rst
--- a/Doc/reference/lexical_analysis.rst
+++ b/Doc/reference/lexical_analysis.rst
@@ -405,7 +405,8 @@
 
 .. productionlist::
    stringliteral: [`stringprefix`](`shortstring` | `longstring`)
-   stringprefix: "r" | "u" | "R" | "U"
+   stringprefix: "r" | "u" | "R" | "U" | "f" | "F"
+               : | "fr" | "Fr" | "fR" | "FR" | "rf" | "rF" | "Rf" | "RF"
    shortstring: "'" `shortstringitem`* "'" | '"' `shortstringitem`* '"'
    longstring: "'''" `longstringitem`* "'''" | '"""' `longstringitem`* '"""'
    shortstringitem: `shortstringchar` | `stringescapeseq`
@@ -464,6 +465,11 @@
    to simplify the maintenance of dual Python 2.x and 3.x codebases.
    See :pep:`414` for more information.
 
+A string literal with ``'f'`` or ``'F'`` in its prefix is a
+:dfn:`formatted string literal`; see :ref:`f-strings`.  The ``'f'`` may be
+combined with ``'r'``, but not with ``'b'`` or ``'u'``, therefore raw
+formatted strings are possible, but formatted bytes literals are not.
+
 In triple-quoted literals, unescaped newlines and quotes are allowed (and are
 retained), except that three unescaped quotes in a row terminate the literal.  (A
 "quote" is the character used to open the literal, i.e. either ``'`` or ``"``.)
@@ -584,7 +590,105 @@
 Note that this feature is defined at the syntactical level, but implemented at
 compile time.  The '+' operator must be used to concatenate string expressions
 at run time.  Also note that literal concatenation can use different quoting
-styles for each component (even mixing raw strings and triple quoted strings).
+styles for each component (even mixing raw strings and triple quoted strings),
+and formatted string literals may be concatenated with plain string literals.
+
+
+.. index::
+   single: formatted string literal
+   single: interpolated string literal
+   single: string; formatted literal
+   single: string; interpolated literal
+   single: f-string
+.. _f-strings:
+
+Formatted string literals
+-------------------------
+
+.. versionadded:: 3.6
+
+A :dfn:`formatted string literal` or :dfn:`f-string` is a string literal
+that is prefixed with ``'f'`` or ``'F'``.  These strings may contain
+replacement fields, which are expressions delimited by curly braces ``{}``.
+While other string literals always have a constant value, formatted strings
+are really expressions evaluated at run time.
+
+Escape sequences are decoded like in ordinary string literals (except when
+a literal is also marked as a raw string).  After decoding, the grammar
+for the contents of the string is:
+
+.. productionlist::
+   f_string: (`literal_char` | "{{" | "}}" | `replacement_field`)*
+   replacement_field: "{" `f_expression` ["!" `conversion`] [":" `format_spec`] "}"
+   f_expression: `conditional_expression` ("," `conditional_expression`)* [","]
+               : | `yield_expression`
+   conversion: "s" | "r" | "a"
+   format_spec: (`literal_char` | NULL | `replacement_field`)*
+   literal_char: <any code point except "{", "}" or NULL>
+
+The parts of the string outside curly braces are treated literally,
+except that any doubled curly braces ``'{{'`` or ``'}}'`` are replaced
+with the corresponding single curly brace.  A single opening curly
+bracket ``'{'`` marks a replacement field, which starts with a
+Python expression.  After the expression, there may be a conversion field,
+introduced by an exclamation point ``'!'``.  A format specifier may also
+be appended, introduced by a colon ``':'``.  A replacement field ends
+with a closing curly bracket ``'}'``.
+
+Expressions in formatted string literals are treated like regular
+Python expressions surrounded by parentheses, with a few exceptions.
+An empty expression is not allowed, and a :keyword:`lambda` expression
+must be surrounded by explicit parentheses.  Replacement expressions
+can contain line breaks (e.g. in triple-quoted strings), but they
+cannot contain comments.  Each expression is evaluated in the context
+where the formatted string literal appears, in order from left to right.
+
+If a conversion is specified, the result of evaluating the expression
+is converted before formatting.  Conversion ``'!s'`` calls :func:`str` on
+the result, ``'!r'`` calls :func:`repr`, and ``'!a'`` calls :func:`ascii`.
+
+The result is then formatted using the :func:`format` protocol.  The
+format specifier is passed to the :meth:`__format__` method of the
+expression or conversion result.  An empty string is passed when the
+format specifier is omitted.  The formatted result is then included in
+the final value of the whole string.
+
+Top-level format specifiers may include nested replacement fields.
+These nested fields may include their own conversion fields and
+format specifiers, but may not include more deeply-nested replacement fields.
+
+Formatted string literals may be concatenated, but replacement fields
+cannot be split across literals.
+
+Some examples of formatted string literals::
+
+   >>> name = "Fred"
+   >>> f"He said his name is {name!r}."
+   "He said his name is 'Fred'."
+   >>> f"He said his name is {repr(name)}."  # repr() is equivalent to !r
+   "He said his name is 'Fred'."
+   >>> width = 10
+   >>> precision = 4
+   >>> value = decimal.Decimal("12.34567")
+   >>> f"result: {value:{width}.{precision}}"  # nested fields
+   'result:      12.35'
+
+A consequence of sharing the same syntax as regular string literals is
+that characters in the replacement fields must not conflict with the
+quoting used in the outer formatted string literal.  Also, escape
+sequences normally apply to the outer formatted string literal,
+rather than inner string literals::
+
+   f"abc {a["x"]} def"    # error: outer string literal ended prematurely
+   f"abc {a[\"x\"]} def"  # workaround: escape the inner quotes
+   f"abc {a['x']} def"    # workaround: use different quoting
+
+   f"newline: {ord('\n')}"   # error: literal line break in inner string
+   f"newline: {ord('\\n')}"  # workaround: double escaping
+   fr"newline: {ord('\n')}"  # workaround: raw outer string
+
+See also :pep:`498` for the proposal that added formatted string literals,
+and :meth:`str.format`, which uses a related format string mechanism.
 
 
 .. _numbers:
diff --git a/Doc/tutorial/inputoutput.rst b/Doc/tutorial/inputoutput.rst
--- a/Doc/tutorial/inputoutput.rst
+++ b/Doc/tutorial/inputoutput.rst
@@ -25,7 +25,8 @@
 concatenation operations you can create any layout you can imagine.  The
 string type has some methods that perform useful operations for padding
 strings to a given column width; these will be discussed shortly.  The second
-way is to use the :meth:`str.format` method.
+way is to use :ref:`formatted string literals <f-strings>`, or the
+:meth:`str.format` method.
 
 The :mod:`string` module contains a :class:`~string.Template` class which offers
 yet another way to substitute values into strings.
diff --git a/Doc/tutorial/introduction.rst b/Doc/tutorial/introduction.rst
--- a/Doc/tutorial/introduction.rst
+++ b/Doc/tutorial/introduction.rst
@@ -352,6 +352,9 @@
       Strings support a large number of methods for
       basic transformations and searching.
 
+   :ref:`f-strings`
+      String literals that have embedded expressions.
+
    :ref:`formatstrings`
       Information about string formatting with :meth:`str.format`.
 
diff --git a/Doc/whatsnew/3.6.rst b/Doc/whatsnew/3.6.rst
--- a/Doc/whatsnew/3.6.rst
+++ b/Doc/whatsnew/3.6.rst
@@ -62,7 +62,7 @@
 .. This section singles out the most important changes in Python 3.6.
    Brevity is key.
 
-* None yet.
+* PEP 498: :ref:`Formatted string literals <whatsnew-fstrings>`
 
 .. PEP-sized items next.
 
@@ -80,6 +80,24 @@
        PEP written by Carl Meyer
 
 
+.. _whatsnew-fstrings:
+
+PEP 498: Formatted string literals
+----------------------------------
+
+Formatted string literals are a new kind of string literal, prefixed
+with ``'f'``.  They are similar to the format strings accepted by
+:meth:`str.format`.  They contain replacement fields surrounded by
+curly braces.  The replacement fields are expressions, which are
+evaluated at run time, and then formatted using the :func:`format` protocol.
+
+    >>> name = "Fred"
+    >>> f"He said his name is {name}."
+    'He said his name is Fred.'
+
+See :pep:`498` and the main documentation at :ref:`f-strings`.
+
+
 Other Language Changes
 ======================
 

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list