@@ -637,9 +637,11 @@ and formatted string literals may be concatenated with plain string literals.
637637 single: string; formatted literal
638638 single: string; interpolated literal
639639 single: f-string
640+ single: fstring
640641 single: {} (curly brackets); in formatted string literal
641642 single: ! (exclamation); in formatted string literal
642643 single: : (colon); in formatted string literal
644+ single: = (equals); for help in debugging using string literals
643645.. _f-strings :
644646
645647Formatted string literals
@@ -659,7 +661,7 @@ for the contents of the string is:
659661
660662.. productionlist ::
661663 f_string: (`literal_char ` | "{{" | "}}" | `replacement_field `)*
662- replacement_field: "{" `f_expression ` ["!" `conversion `] [":" `format_spec `] "}"
664+ replacement_field: "{" `f_expression ` ["="] [" !" `conversion `] [":" `format_spec `] "}"
663665 f_expression: (`conditional_expression ` | "*" `or_expr `)
664666 : ("," `conditional_expression ` | "," "*" `or_expr `)* [","]
665667 : | `yield_expression `
@@ -671,10 +673,11 @@ The parts of the string outside curly braces are treated literally,
671673except that any doubled curly braces ``'{{' `` or ``'}}' `` are replaced
672674with the corresponding single curly brace. A single opening curly
673675bracket ``'{' `` marks a replacement field, which starts with a
674- Python expression. After the expression, there may be a conversion field,
675- introduced by an exclamation point ``'!' ``. A format specifier may also
676- be appended, introduced by a colon ``':' ``. A replacement field ends
677- with a closing curly bracket ``'}' ``.
676+ Python expression. To display both the expression text and its value after
677+ evaluation, (useful in debugging), an equal sign ``'=' `` may be added after the
678+ expression. A conversion field, introduced by an exclamation point ``'!' `` may
679+ follow. A format specifier may also be appended, introduced by a colon ``':' ``.
680+ A replacement field ends with a closing curly bracket ``'}' ``.
678681
679682Expressions in formatted string literals are treated like regular
680683Python expressions surrounded by parentheses, with a few exceptions.
@@ -690,6 +693,17 @@ left to right.
690693 containing an :keyword: `async for ` clause were illegal in the expressions
691694 in formatted string literals due to a problem with the implementation.
692695
696+ When the equal sign ``'=' `` is provided, the output will have the expression
697+ text, the ``'=' `` and the evaluated value. Spaces after the opening brace
698+ ``'{' ``, within the expression and after the ``'=' `` are all retained in the
699+ output. By default, the ``'=' `` causes the :func: `repr ` of the expression to be
700+ provided, unless there is a format specified. When a format is specified it
701+ defaults to the :func: `str ` of the expression unless a conversion ``'!r' `` is
702+ declared.
703+
704+ .. versionadded :: 3.8
705+ The equal sign ``'=' `` was added in Python 3.8.
706+
693707If a conversion is specified, the result of evaluating the expression
694708is converted before formatting. Conversion ``'!s' `` calls :func: `str ` on
695709the result, ``'!r' `` calls :func: `repr `, and ``'!a' `` calls :func: `ascii `.
@@ -724,9 +738,22 @@ Some examples of formatted string literals::
724738 >>> today = datetime(year=2017, month=1, day=27)
725739 >>> f"{today:%B %d, %Y}" # using date format specifier
726740 'January 27, 2017'
741+ >>> f"{today=:%B %d, %Y}" # using date format specifier and debugging
742+ 'today=January 27, 2017'
727743 >>> number = 1024
728744 >>> f"{number:#0x}" # using integer format specifier
729745 '0x400'
746+ >>> foo = "bar"
747+ >>> f"{ foo = }" # preserves whitespace
748+ " foo = 'bar'"
749+ >>> line = "The mill's closed"
750+ >>> f"{line = }"
751+ 'line = "The mill\'s closed"'
752+ >>> f"{line = :20}"
753+ "line = The mill's closed "
754+ >>> f"{line = !r:20}"
755+ 'line = "The mill\'s closed" '
756+
730757
731758A consequence of sharing the same syntax as regular string literals is
732759that characters in the replacement fields must not conflict with the
0 commit comments