From 0e29282b63521fb070d279ec4106f34b18d05a6c Mon Sep 17 00:00:00 2001 From: Dave Date: Fri, 11 Apr 2025 07:52:05 -0700 Subject: [PATCH 1/5] Spec fix: make the debug spec section fully match f-string behavior --- peps/pep-0750.rst | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/peps/pep-0750.rst b/peps/pep-0750.rst index 92ec3c34cea..dda0ec1bf9a 100644 --- a/peps/pep-0750.rst +++ b/peps/pep-0750.rst @@ -455,7 +455,9 @@ The debug specifier, ``=``, is supported in template strings and behaves similar to how it behaves in f-strings, though due to limitations of the implementation there is a slight difference. -In particular, ``t'{value=}'`` is treated as ``t'value={value!r}'``: +In particular, ``t'{value=}'`` is treated as ``t'value={value!r}'``. The first +static string is rewritten from ``""`` to ``"value="`` and the conversion +defaults to ``r``: .. code-block:: python @@ -465,8 +467,11 @@ In particular, ``t'{value=}'`` is treated as ``t'value={value!r}'``: assert template.interpolations[0].value == "World" assert template.interpolations[0].conversion == "r" -If a separate format string is also provided, ``t'{value=:fmt}`` is treated -instead as ``t'value={value!s:fmt}'``. +If a conversion is explicitly provided, it is kept: ``t'{value=:s}'`` +is treated as ``t'value={value!s}'``. + +If a format string is provided without a conversion, the ``conversion`` +is set to ``None``: ``t'{value=:fmt}'`` is treated as ``t'value={value:fmt}'``. Whitespace is preserved in the debug specifier, so ``t'{value = }'`` is treated as ``t'value = {value!r}'``. From 954899c56accfdd852f6417f34b0c2f4a8efe99b Mon Sep 17 00:00:00 2001 From: Dave Date: Fri, 11 Apr 2025 08:02:07 -0700 Subject: [PATCH 2/5] Fix lint issue --- peps/pep-0750.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/peps/pep-0750.rst b/peps/pep-0750.rst index dda0ec1bf9a..e1ef10eca9c 100644 --- a/peps/pep-0750.rst +++ b/peps/pep-0750.rst @@ -456,7 +456,7 @@ to how it behaves in f-strings, though due to limitations of the implementation there is a slight difference. In particular, ``t'{value=}'`` is treated as ``t'value={value!r}'``. The first -static string is rewritten from ``""`` to ``"value="`` and the conversion +static string is rewritten from ``""`` to ``"value="`` and the conversion defaults to ``r``: .. code-block:: python From 3ee52996b12f7de01cb4901705739951aef9df26 Mon Sep 17 00:00:00 2001 From: Dave Date: Fri, 11 Apr 2025 08:08:10 -0700 Subject: [PATCH 3/5] !s, not :s --- peps/pep-0750.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/peps/pep-0750.rst b/peps/pep-0750.rst index e1ef10eca9c..5369e855a12 100644 --- a/peps/pep-0750.rst +++ b/peps/pep-0750.rst @@ -467,7 +467,7 @@ defaults to ``r``: assert template.interpolations[0].value == "World" assert template.interpolations[0].conversion == "r" -If a conversion is explicitly provided, it is kept: ``t'{value=:s}'`` +If a conversion is explicitly provided, it is kept: ``t'{value=!s}'`` is treated as ``t'value={value!s}'``. If a format string is provided without a conversion, the ``conversion`` From 51ca27edeb59c5e33e46eb87b760d105c5907c69 Mon Sep 17 00:00:00 2001 From: Dave Date: Fri, 11 Apr 2025 08:08:52 -0700 Subject: [PATCH 4/5] conversion --- peps/pep-0750.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/peps/pep-0750.rst b/peps/pep-0750.rst index 5369e855a12..c1e2c92a000 100644 --- a/peps/pep-0750.rst +++ b/peps/pep-0750.rst @@ -456,7 +456,7 @@ to how it behaves in f-strings, though due to limitations of the implementation there is a slight difference. In particular, ``t'{value=}'`` is treated as ``t'value={value!r}'``. The first -static string is rewritten from ``""`` to ``"value="`` and the conversion +static string is rewritten from ``""`` to ``"value="`` and the ``conversion`` defaults to ``r``: .. code-block:: python From 77fe76587664db32e4fd8f29661d1a470ac6603e Mon Sep 17 00:00:00 2001 From: Dave Date: Thu, 26 Jun 2025 10:09:24 -0700 Subject: [PATCH 5/5] Clarify behavior of `Interpolation.expression` and add a default value. --- peps/pep-0750.rst | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/peps/pep-0750.rst b/peps/pep-0750.rst index c1e2c92a000..b06cbbce2be 100644 --- a/peps/pep-0750.rst +++ b/peps/pep-0750.rst @@ -209,7 +209,7 @@ Like ``Template``, it is a new class found in the :mod:`!string.templatelib` mod def __new__( cls, value: object, - expression: str, + expression: str = "", conversion: Literal["a", "r", "s"] | None = None, format_spec: str = "", ): @@ -226,7 +226,8 @@ The ``value`` attribute is the evaluated result of the interpolation: template = t"Hello {name}" assert template.interpolations[0].value == "World" -The ``expression`` attribute is the *original text* of the interpolation: +When interpolations are created from a template string literal, the +``expression`` attribute contains the *original text* of the interpolation: .. code-block:: python @@ -234,6 +235,11 @@ The ``expression`` attribute is the *original text* of the interpolation: template = t"Hello {name}" assert template.interpolations[0].expression == "name" +When developers explicitly construct an ``Interpolation``, they may optionally +provide a value for the ``expression`` attribute. Even though it is stored as +a string, this *should* be a valid Python expression. If no value is provided, +the ``expression`` attribute defaults to the empty string (``""``). + We expect that the ``expression`` attribute will not be used in most template processing code. It is provided for completeness and for use in debugging and introspection. See both the `Common Patterns Seen in Processing Templates`_