[Python-checkins] peps (merge default -> default): merge

donald.stufft python-checkins at python.org
Sat Aug 29 17:05:55 CEST 2015


https://hg.python.org/peps/rev/036f89f3cea8
changeset:   6008:036f89f3cea8
parent:      6007:8cc94276db23
parent:      6006:9af8765a7661
user:        Donald Stufft <donald at stufft.io>
date:        Sat Aug 29 10:40:35 2015 -0400
summary:
  merge

files:
  pep-0498.txt |  91 ++++++++++++++++++++++++++++++++++++---
  pep-0501.txt |   2 +-
  2 files changed, 85 insertions(+), 8 deletions(-)


diff --git a/pep-0498.txt b/pep-0498.txt
--- a/pep-0498.txt
+++ b/pep-0498.txt
@@ -208,6 +208,25 @@
 brackets, or braces. The exception is that the '!=' operator is
 special cased.
 
+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::
+
+  >>> f'\u007b4*10}'
+  '40'
+  >>> f'\x7b4*10}'
+  '40'
+  >>> f'\x7b4*10\N{RIGHT CURLY BRACKET}'
+  '40'
+
+These examples aren't generally useful, they're just to show that
+escape sequences are processed before f-strings are parsed for
+expressions.
+
 Code equivalence
 ----------------
 
@@ -360,6 +379,25 @@
 For ease of readability, leading and trailing whitespace in
 expressions is ignored.
 
+Evaluation order of expressions
+-------------------------------
+
+The expressions in an f-string are evaluated in left-to-right
+order. This is detectable only if the expressions have side effects::
+
+  >>> def fn(l, incr):
+  ...    result = l[0]
+  ...    l[0] += incr
+  ...    return result
+  ...
+  >>> lst = [0]
+  >>> f'{fn(lst,2)} {fn(lst,3)}'
+  '0 2'
+  >>> f'{fn(lst,2)} {fn(lst,3)}'
+  '5 7'
+  >>> lst
+  [10]
+
 Discussion
 ==========
 
@@ -403,7 +441,7 @@
 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
+\\{ 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
@@ -473,6 +511,15 @@
 See [#]_ for a further discussion. It was this observation that led to
 full Python expressions being supported in f-strings.
 
+Furthermore, the limited expressions that str.format() understands
+need not be valid Python expressions. For example::
+
+  >>> '{i[";]}'.format(i={'";':4})
+  '4'
+
+For this reason, the str.format() "expression parser" is not suitable
+for use when implementing f-strings.
+
 Triple-quoted f-strings
 -----------------------
 
@@ -593,15 +640,45 @@
 
   f'{x:.{width}}'
 
-Expressions with side effects
------------------------------
+The same expression used multiple times
+---------------------------------------
 
-xxx
+Every expression in braces in an f-string is evaluated exactly
+once. If the same expression is used more than once in the same
+f-string, it will be evaluated multiple times. However, it's undefined
+which result will show up in the resulting string value. For purposes
+of this section, two expressions are the same if they have the exact
+same literal text defining them. For example, '{i}' and '{i}' are the
+same expression, but '{i}' and '{ i}' are not, due to the extra space
+in the second expression.
 
-Expressions used multiple times
--------------------------------
+For example, given::
 
-xxx
+  >>> def fn(lst):
+  ...    lst[0] += 1
+  ...    return lst[0]
+  ...
+  >>> lst=[0]
+  >>> f'{fn(lst)} {fn(lst)}'
+  '1 2'
+
+The resulting f-string might have the value '1 2', '2 2', '1 1', or
+even '2 1'.
+
+However::
+
+  >>> lst=[0]
+  >>> f'{fn(lst)} { fn(lst)}'
+  '1 2'
+
+This f-string will always have the value '1 2'. This is due to the two
+expressions not being the same: the space in the second example makes
+the two expressions distinct.
+
+This restriction is in place in order to allow for a possible future
+extension allowing translated strings, wherein the expression
+substitutions would be identified by their text values as they show up
+between the braces.
 
 References
 ==========
diff --git a/pep-0501.txt b/pep-0501.txt
--- a/pep-0501.txt
+++ b/pep-0501.txt
@@ -166,7 +166,7 @@
         __slots__ = ("raw_template", "parsed_fields", "field_values")
 
         def __new__(cls, raw_template, parsed_fields, field_values):
-            self = super().__new__()
+            self = super().__new__(cls)
             self.raw_template = raw_template
             self.parsed_fields = parsed_fields
             self.field_values = field_values

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


More information about the Python-checkins mailing list