Make it clear that __format__ isn't called on the value of each expression, but rather on the type of the value. This is how the builtin format() function works, too.

This commit is contained in:
Eric V. Smith 2015-09-19 11:24:19 -04:00
parent 89ebf86c06
commit e3e40dd1d2
1 changed files with 12 additions and 7 deletions

View File

@ -8,7 +8,7 @@ Type: Standards Track
Content-Type: text/x-rst Content-Type: text/x-rst
Created: 01-Aug-2015 Created: 01-Aug-2015
Python-Version: 3.6 Python-Version: 3.6
Post-History: 07-Aug-2015, 30-Aug-2015, 04-Sep-2015 Post-History: 07-Aug-2015, 30-Aug-2015, 04-Sep-2015, 19-Sep-2015
Resolution: https://mail.python.org/pipermail/python-dev/2015-September/141526.html Resolution: https://mail.python.org/pipermail/python-dev/2015-September/141526.html
Abstract Abstract
@ -201,6 +201,11 @@ 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. 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.
Comments, using the ``'#'`` character, are not allowed inside an Comments, using the ``'#'`` character, are not allowed inside an
expression. expression.
@ -209,7 +214,7 @@ specified. The allowed conversions are ``'!s'``, ``'!r'``, or
``'!a'``. These are treated the same as in ``str.format()``: ``'!s'`` ``'!a'``. These are treated the same as in ``str.format()``: ``'!s'``
calls ``str()`` on the expression, ``'!r'`` calls ``repr()`` on the calls ``str()`` on the expression, ``'!r'`` calls ``repr()`` on the
expression, and ``'!a'`` calls ``ascii()`` on the expression. These expression, and ``'!a'`` calls ``ascii()`` on the expression. These
conversions are applied before the call to ``__format__``. The only conversions are applied before the call to ``format()``. The only
reason to use ``'!s'`` is if you want to specify a format specifier reason to use ``'!s'`` is if you want to specify a format specifier
that applies to ``str``, not to the type of the expression. that applies to ``str``, not to the type of the expression.
@ -222,9 +227,9 @@ So, an f-string looks like::
f ' <text> { <expression> <optional !s, !r, or !a> <optional : format specifier> } <text> ... ' f ' <text> { <expression> <optional !s, !r, or !a> <optional : format specifier> } <text> ... '
The resulting expression's ``__format__`` method is called with the The expression is then formatted using the ``__format__`` protocol,
format specifier as an argument. The resulting value is used when using the format specifier as an argument. The resulting value is
building the value of the f-string. used when building the value of the f-string.
Expressions cannot contain ``':'`` or ``'!'`` outside of strings or Expressions cannot contain ``':'`` or ``'!'`` outside of strings or
parentheses, brackets, or braces. The exception is that the ``'!='`` parentheses, brackets, or braces. The exception is that the ``'!='``
@ -293,7 +298,7 @@ For example, this code::
Might be be evaluated as:: Might be be evaluated as::
'abc' + expr1.__format__(spec1) + repr(expr2).__format__(spec2) + 'def' + str(expr3).__format__('') + 'ghi' 'abc' + format(expr1, spec1) + format(repr(expr2)) + 'def' + format(str(expr3)) + 'ghi'
Expression evaluation Expression evaluation
--------------------- ---------------------
@ -371,7 +376,7 @@ yields the value::
While the exact method of this run time concatenation is unspecified, While the exact method of this run time concatenation is unspecified,
the above code might evaluate to:: the above code might evaluate to::
'ab' + x.__format__('') + '{c}' + 'str<' + y.__format__('^4') + '>de' 'ab' + format(x) + '{c}' + 'str<' + format(y, '^4') + '>de'
Each f-string is entirely evaluated before being concatenated to Each f-string is entirely evaluated before being concatenated to
adjacent f-strings. That means that this:: adjacent f-strings. That means that this::