PEP 501: Minor editing fixes (#3946)

Also fixes an incorrect comment about the impact
a CPython operand precedence bug will have on the
way template literals interact with regular strings.
This commit is contained in:
Alyssa Coghlan 2024-09-13 18:53:53 +10:00 committed by GitHub
parent 256b644fb3
commit e660248bea
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 28 additions and 19 deletions

View File

@ -22,8 +22,9 @@ can be vulnerable to injection attacks when used to construct
shell commands, SQL queries, HTML snippets and similar
(for example, ``os.system(f"echo {message_from_user}")``).
This PEP introduces template literal strings (or "t-strings"),
which have the same syntax and semantics but with rendering deferred
until :func:`format` or another template rendering function is called on them.
which have syntax and semantics that are similar to f-strings,
but with rendering deferred until :func:`format` or another
template rendering function is called on them.
This will allow standard library calls, helper functions
and third party tools to safety and intelligently perform
appropriate escaping and other string processing on inputs
@ -49,7 +50,7 @@ inspired by the tagged strings proposal).
This PEP does NOT propose an alternative to :pep:`292` for user interface
internationalization use cases (but does note the potential for future syntactic
enhancements aimed at that use case that would benefit from the compiler-support
enhancements aimed at that use case that would benefit from the compiler-supported
value interpolation machinery that this PEP and :pep:`750` introduce).
@ -85,7 +86,7 @@ help make it easier to write code that uses safer alternatives (such as
To address that problem (and a number of other concerns), this PEP proposes
the complementary introduction of "t-strings" (a mnemonic for "template literal strings"),
where ``format(t"Message with {data}")`` would produce the same result as
``f"Message with {data}"``, but the interpolation template instance can instead be passed
``f"Message with {data}"``, but the template literal instance can instead be passed
to other template rendering functions which process the contents of the template
differently.
@ -150,8 +151,8 @@ Lazy field evaluation conversion specifier
------------------------------------------
In addition to the existing support for the ``a``, ``r``, and ``s`` conversion specifiers,
:meth:`str.format` and :meth:`str.format_map` will be updated to accept ``()`` as a
conversion specifier that means "call the interpolated value".
:meth:`str.format`, :meth:`str.format_map`, and :class:`string.Formatter` will be updated
to accept ``()`` as a conversion specifier that means "call the interpolated value".
To support application of the standard conversion specifiers in custom template rendering
functions, a new :func:`!operator.convert_field` function will be added.
@ -169,9 +170,12 @@ To allow additional field-specific directives to be passed to custom rendering f
a way that still allows formatting of the template with the default renderer, the conversion
specifier field will be allowed to contain a second ``!`` character.
:func:`!operator.convert_field` and :func:`format` (and hence the default template rendering
function) will ignore that character and any subsequent text in the conversion specifier
field.
:func:`!operator.convert_field` and :func:`format` (and hence the default
``TemplateLiteral.render`` template rendering method), will ignore that character and any
subsequent text in the conversion specifier field.
:meth:`str.format`, :meth:`str.format_map`, and :class:`string.Formatter` will also be
updated to accept (and ignore) custom conversion specifiers.
Template renderer for POSIX shell commands
@ -223,8 +227,13 @@ The key differences between f-strings and t-strings are:
* unlike f-strings (where conversion specifiers are handled directly in the compiler),
t-string conversion specifiers are handled at rendering time by the rendering function
* the new ``!()`` conversion specifier indicates that the field expression is a callable
that should be called when using the default :func:`format` rendering function. This specifier
is specifically *not* being added to f-strings (since it is pointless there).
that should be called when using the default :func:`format` rendering function. This
specifier is specifically *not* being added to f-strings (since it is pointless there).
* a second ``!`` is allowed in t-string conversion specifiers (with any subsequent text
being ignored) as a way to allow custom template rendering functions to accept custom
conversion specifiers without breaking the default :func:`!TemplateLiteral.render`
rendering method. This feature is specifically *not* being added to f-strings (since
it is pointless there).
* while f-string ``f"Message {here}"`` would be *semantically* equivalent to
``format(t"Message {here}")``, f-strings will continue to be supported directly in the
compiler and hence avoid the runtime overhead of actually using the delayed rendering
@ -262,8 +271,8 @@ cosmetic than substantive. In particular:
* this PEP proposes exact details for the proposed APIs of the concrete implementation types
(including concatenation and repetition support, which are not part of the structural
typing protocols)
* this PEP proposes changes to the existing :func:`format` builtin to make it usable directly as
template field renderer
* this PEP proposes changes to the existing :func:`format` builtin to make it usable
directly as a template field renderer
The two PEPs also differ in *how* they make their case for delayed rendering support. This
PEP focuses more on the concrete implementation concept of using template literals to allow
@ -316,7 +325,7 @@ entire combined literal forming the template literal.
The template string is parsed into literals, expressions, format specifiers, and conversion
specifiers as described for f-strings in :pep:`498` and :pep:`701`. The syntax for conversion
specifiers is relaxed such that arbitrary strings are accepted (excluding those containing
``{``, ``}`` and ``:``) rather than being restricted to valid Python identifiers.
``{``, ``}`` or ``:``) rather than being restricted to valid Python identifiers.
However, rather than being rendered directly into a formatted string, these
components are instead organised into instances of new types with the
@ -493,9 +502,9 @@ following behaviour:
def __radd__(self, other) -> TemplateLiteral|NotImplemented:
if isinstance(other, str):
# Treat the given string as a new raw text segment. This will likely never
# run in practice due to https://github.com/python/cpython/issues/55686,
# but it at least makes the *intended* behaviour in this case clear.
# Treat the given string as a new raw text segment. This effectively
# has precedence over string concatenation in CPython due to
# https://github.com/python/cpython/issues/55686
combined_raw_text = other + self._raw
combined_segments = (TemplateLiteralText(other),) + self._segments
return TemplateLiteral(combined_raw_text, *combined_segments)
@ -731,7 +740,7 @@ Structural typing and duck typing
---------------------------------
To allow custom renderers to accept alternative interpolation template implementations
(rather than being tightly coupled to the native interpolation template types), the
(rather than being tightly coupled to the native template literal types), the
following structural protocols will be added to the ``typing`` module:
.. code-block:: python
@ -1155,7 +1164,7 @@ fields in format specifiers).
Defining repetition and concatenation semantics
-----------------------------------------------
This PEPs explicitly defines repetition and concatenation semantics for ``TemplateLiteral``
This PEP explicitly defines repetition and concatenation semantics for ``TemplateLiteral``
and ``TemplateLiteralText``. While not strictly necessary, defining these is expected
to make the types easier to work with in code that historically only supported regular
strings.