Skip to content

PEP 750: restrict support for Template + str addition #4395

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 39 additions & 28 deletions peps/pep-0750.rst
Original file line number Diff line number Diff line change
Expand Up @@ -394,37 +394,44 @@ Template String Concatenation
-----------------------------

Template strings support explicit concatenation using ``+``. Concatenation is
supported for two ``Template`` instances as well as for a ``Template`` instance
and a ``str``:
supported for two ``Template`` instances via ``Template.__add__()``:

.. code-block:: python

name = "World"
template = t"{name}"

assert isinstance(t"Hello " + template, Template)
assert (t"Hello " + template).strings == ("Hello ", "")
assert (t"Hello " + template).interpolations[0].value == "World"
assert isinstance(t"Hello " + t"{name}", Template)
assert (t"Hello " + t"{name}").strings == ("Hello ", "")
assert (t"Hello " + t"{name}").values[0] == "World"

assert isinstance("Hello " + template, Template)
assert ("Hello " + template).strings == ("Hello ", "")
assert ("Hello " + template).interpolations[0].value == "World"
Implicit concatenation of two template string literals is also supported:

Concatenation of templates is "viral": the concatenation of a ``Template`` and
a ``str`` always results in a ``Template`` instance.
.. code-block:: python

name = "World"
assert isinstance(t"Hello " t"{name}", Template)
assert (t"Hello " t"{name}").strings == ("Hello ", "")
assert (t"Hello " t"{name}").values[0] == "World"

Both implicit and explicit concatenation of ``Template`` and ``str`` is
prohibited. This is because it is ambiguous whether the ``str`` should be
treated as a static string part or as an interpolation.

Python's implicit concatenation syntax is also supported. The following code
will work as expected:
To combine a ``Template`` and a ``str``, developers must explicitly decide how
to treat the ``str``. If the ``str`` is intended to be a static string part,
it should be wrapped in a ``Template``. If the ``str`` is intended to be an
interpolation value, it should be wrapped in an ``Interpolation`` and
passed to the ``Template`` constructor. For example:

.. code-block:: python

name = "World"
assert (t"Hello " t"World").strings == ("Hello World",)
assert ("Hello " t"World").strings == ("Hello World",)

The ``Template`` type supports the ``__add__()`` and ``__radd__()`` methods
between two ``Template`` instances and between a ``Template`` instance and a
``str``.
# Treat `name` as a static string part
template = t"Hello " + Template(name)

# Treat `name` as an interpolation
template = t"Hello " + Template(Interpolation(name, "name"))


Template and Interpolation Equality
Expand Down Expand Up @@ -1349,11 +1356,12 @@ Developers who need to obtain the original template string literal can always
use ``inspect.getsource()`` or similar tools.


Disallowing String Concatenation
--------------------------------
Disallowing Template Concatenation
----------------------------------

Earlier versions of this PEP proposed that template strings should not support
concatenation. This was rejected in favor of allowing concatenation.
Earlier versions of this PEP proposed that ``Template`` instances should not
support concatenation. This was rejected in favor of allowing concatenating
multiple ``Template`` instances.

There are reasonable arguments in favor of rejecting one or all forms of
concatenation: namely, that it cuts off a class of potential bugs, particularly
Expand All @@ -1367,13 +1375,16 @@ return a type that supported concatenation.

In the end, we decided that the surprise to developers of a new string type
*not* supporting concatenation was likely to be greater than the theoretical
harm caused by supporting it. (Developers concatenate f-strings all the time,
after all, and while we are sure there are cases where this introduces bugs,
it's not clear that those bugs outweigh the benefits of supporting concatenation.)
harm caused by supporting it.

While concatenation of two ``Templates`` is supported by this PEP, concatenation
of a ``Template`` and a ``str`` is not supported. This is because it is
ambiguous whether ``str`` should be treated as a static string or an
interpolation. Developers must wrap the ``str`` in a ``Template`` instance
before concatenating it with another ``Template``, as described above.

While concatenation is supported, we expect that code that uses template strings
will more commonly build up larger templates through nesting and composition
rather than concatenation.
We expect that code that uses template strings will more commonly build up
larger templates through nesting and composition rather than concatenation.


Arbitrary Conversion Values
Expand Down