[Python-checkins] peps: Remove str.interpolate. It's just an implementation detail. It can be exposed
eric.smith
python-checkins at python.org
Mon Aug 24 20:34:49 CEST 2015
https://hg.python.org/peps/rev/ec11060d2f52
changeset: 5985:ec11060d2f52
user: Eric V. Smith <eric at trueblade.com>
date: Mon Aug 24 14:35:44 2015 -0400
summary:
Remove str.interpolate. It's just an implementation detail. It can be exposed at a later date, if need be.
files:
pep-0498.txt | 115 +++-----------------------------------
1 files changed, 10 insertions(+), 105 deletions(-)
diff --git a/pep-0498.txt b/pep-0498.txt
--- a/pep-0498.txt
+++ b/pep-0498.txt
@@ -41,9 +41,6 @@
>>> f'He said his name is {name!r}.'
"He said his name is 'Fred'."
-This PEP proposes a new method on the str type:
-str.interpolate(). This method will be used to implement f-strings.
-
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
@@ -164,11 +161,6 @@
globals() has access to far more information than needed to do the
string interpolation.
-If locals() and globals() were used, and if a future extension to this
-PEP would add an internationalization layer before str.interpolate()
-is called, a malicious translator could get access to additional
-variables in the callers context.
-
Guido stated [#]_ that any solution to better string interpolation
would not use locals() or globals().
@@ -216,58 +208,21 @@
brackets, or braces. The exception is that the '!=' operator is
special cased.
-str.interpolate()
------------------
-
-str.interpolate(mapping) will be a new method on the str type. It
-takes one argument: a mapping of field names to values. This method is
-the same as str.format_map() [#]_, with one difference: it does not
-interpret the field_name [#]_ in any way. The field_name is only used
-to look up the replacement value in the supplied mapping object. Like
-str.format() and str.format_map(), str.interpolate() does interpret
-and apply the optional conversion and format_spec. Thus, a field_name
-may not contain the characters ':' or '}', nor the strings '!s', '!r',
-or '!a'.
-
-Examples::
-
- >>> name = 'Guido'
- >>> 'name={name}'.interpolate({'name': name})
- 'name=Guido'
-
- >>> '{date} was on a {date:%A}. It was {weather}.'.interpolate({'weather': 'sunny', 'date': datetime.date(1991, 10, 12)})
- '1991-10-12 was on a Saturday. It was sunny.'
-
-Like str.format_map(), only the field_name portion inside braces is
-used to look up values in the mapping. The format_spec is not used as
-part of this lookup. Thus::
-
- >>> 'name={name:10}'.interpolate({'name': name})
- 'name=Guido '
-
-But::
-
- >>> 'name={name:10}'.interpolate({'name:10': name})
- Traceback (most recent call last):
- File "<stdin>", line 1, in <module>
- KeyError: 'name'
-
Code equivalence
----------------
-An f-string is evaluated at run time using a call to str.interpolate().
+The exact code used to implement f-strings is not specified. However,
+it is guaranteed that any embedded value that is converted to a string
+will use that value's __format__ method. This is the same mechanism
+that str.format() uses to convert values to strings.
For example, this code::
f'abc{expr1:spec1}{expr2!r:spec2}def{expr3:!s}ghi'
-Will be be evaluated as::
+Might be be evaluated as::
- 'abc{expr1:spec1}{expr2!r:spec2}def{expr3:!s}ghi'.interpolate({'expr1': expr1, 'expr2': expr2, 'expr3': expr3})
-
-Note that the string on which interpolate() is being called is
-identical to the value of the f-string.
-
+ ''.join(['abc', expr1.__format__(spec1), repr(expr2).__format__(spec2), 'def', str(spec3).__format__(''), 'ghi'])
Expression evaluation
---------------------
@@ -350,19 +305,7 @@
While the exact method of this run time concatenation is unspecified,
the above code might evaluate to::
- ''.join(['ab', '{x}'.interpolate({'x': x}), '{c}', 'str<', 'str<{y:^4}>'.interpolate({'y': y}), 'de'])
-
-You are guaranteed, however, that there will be no compile time
-combination of f-strings::
-
- >>> x = 0
- >>> y = 1
- >>> f'{x}' f'{y}'
- '01'
-
-Will result in 2 calls to str.interpolate(): once on the string '{x}',
-and again on the string '{y}'. This guarantee is needed to facilitate
-proposed future internationalization.
+ ''.join(['ab', x.__format__(''), '{c}', 'str<', y.__format__('^4'), 'de'])
Error handling
--------------
@@ -415,16 +358,7 @@
---------------------------------------------------------
For ease of readability, leading and trailing whitespace in
-expressions is ignored. However, this does not affect the string or
-keys passed to str.interpolate()::
-
- >>> x = 100
- >>> f'x = { x }'
- 'x = 100'
-
-This would be evaluated as::
-
- 'x = { x }'.interpolate({' x ': 100})
+expressions is ignored.
Discussion
==========
@@ -544,7 +478,7 @@
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 str.interpolate() is called.
+logic is applied, and __format__() on each value is called.
Raw f-strings
-------------
@@ -612,40 +546,11 @@
a plain lambda in an f-string expression, this is not seen as much of
a limitation.
-Lambdas may be used inside of parens::
+If you feel you must use lambdas, they may be used inside of parens::
>>> f'{(lambda x: x*2)(3)}'
'6'
-Future extensions
-=================
-
-By using another leading character (say, 'i'), we could extend this
-proposal to cover internationalization and localization. The idea is
-that the string would be passed to some lookup function before
-.interpolate() is called on it::
-
- >>> name = 'Eric'
- >>> i'Name: {name}'
-
-Could be translated as::
-
- gettext.gettext('Name: {name}').interpolate({'name': name})
-
-If gettext.gettext() returned '{name} es mi nombre', then the
-resulting string would be 'Eric es mi nombre'.
-
-Any such internationalization work will be specified in an additional
-PEP. In all likelyhood, such a PEP will need to propose one or more
-additional optional parameters to str.interpolate() in order to handle
-the string.Template case of "safe substitution", where the substituted
-field_names are not found in the mapping argument. The choices might
-be: use the field_name, use a default (possibly empty) string, or
-raise an exception.
-
-There would obviously need to be some way to specify to the compiler
-what lookup function would be called.
-
References
==========
--
Repository URL: https://hg.python.org/peps
More information about the Python-checkins
mailing list