]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-134551: Add t-strings support to pprint (#134577)
authorLoïc Simon <loic.simon@espci.org>
Tue, 14 Apr 2026 11:37:41 +0000 (13:37 +0200)
committerGitHub <noreply@github.com>
Tue, 14 Apr 2026 11:37:41 +0000 (14:37 +0300)
Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
Doc/whatsnew/3.15.rst
Lib/pprint.py
Lib/test/test_pprint.py
Misc/NEWS.d/next/Library/2025-05-23-10-28-51.gh-issue-134551.0rnq0X.rst [new file with mode: 0644]

index c754b634ecccfaf1f71086ff68d19a101be80d36..fe2ddfdcd0e9174b57d6fa7ddadde32e096b293e 100644 (file)
@@ -1551,7 +1551,11 @@ pprint
   :func:`pprint.pformat`, :func:`pprint.pp`. If true, the output will be
   formatted similar to pretty-printed :func:`json.dumps` when
   *indent* is supplied.
-  (Contributed by Stefan Todoran and Semyon Moroz in :gh:`112632`.)
+  (Contributed by Stefan Todoran, Semyon Moroz and Hugo van Kemenade in
+  :gh:`112632`.)
+
+* Add t-string support to :mod:`pprint`.
+  (Contributed by Loïc Simon and Hugo van Kemenade in :gh:`134551`.)
 
 
 sre_*
index f197d7d17cdb9666c5806ec1d988749bdfb236bf..7355021998081dcda7bec837fbe6d39a50099631 100644 (file)
@@ -735,6 +735,61 @@ class PrettyPrinter:
 
     _dispatch[_collections.UserString.__repr__] = _pprint_user_string
 
+    def _pprint_template(self, object, stream, indent, allowance, context, level):
+        cls_name = object.__class__.__name__
+        if self._expand:
+            indent += self._indent_per_level
+        else:
+            indent += len(cls_name) + 1
+
+        items = (
+            ("strings", object.strings),
+            ("interpolations", object.interpolations),
+        )
+        stream.write(self._format_block_start(cls_name + "(", indent))
+        self._format_namespace_items(
+            items, stream, indent, allowance, context, level
+        )
+        stream.write(
+            self._format_block_end(")", indent - self._indent_per_level)
+        )
+
+    def _pprint_interpolation(self, object, stream, indent, allowance, context, level):
+        cls_name = object.__class__.__name__
+        if self._expand:
+            indent += self._indent_per_level
+            items = (
+                ("value", object.value),
+                ("expression", object.expression),
+                ("conversion", object.conversion),
+                ("format_spec", object.format_spec),
+            )
+            stream.write(self._format_block_start(cls_name + "(", indent))
+            self._format_namespace_items(
+                items, stream, indent, allowance, context, level
+            )
+            stream.write(
+                self._format_block_end(")", indent - self._indent_per_level)
+            )
+        else:
+            indent += len(cls_name)
+            items = (
+                object.value,
+                object.expression,
+                object.conversion,
+                object.format_spec,
+            )
+            stream.write(cls_name + "(")
+            self._format_items(
+                items, stream, indent, allowance, context, level
+            )
+            stream.write(")")
+
+    t = t"{0}"
+    _dispatch[type(t).__repr__] = _pprint_template
+    _dispatch[type(t.interpolations[0]).__repr__] = _pprint_interpolation
+    del t
+
     def _safe_repr(self, object, context, maxlevels, level):
         # Return triple (repr_string, isreadable, isrecursive).
         typ = type(object)
index 45e081c233f0b024cdf7dd541fe6229c66a18d6b..041c2072b9e253a9ace901508e6c8aa6e0ed8bd5 100644 (file)
@@ -1515,6 +1515,86 @@ ValuesView({'a': 6,
     'jumped over a '
     'lazy dog'}""")
 
+    def test_template(self):
+        d = t""
+        self.assertEqual(pprint.pformat(d),
+                         "Template(strings=('',), interpolations=())")
+        self.assertEqual(pprint.pformat(d), repr(d))
+        self.assertEqual(pprint.pformat(d, width=1),
+"""\
+Template(strings=('',),
+         interpolations=())""")
+        name = "World"
+        d = t"Hello {name}"
+        self.assertEqual(pprint.pformat(d),
+"""\
+Template(strings=('Hello ', ''),
+         interpolations=(Interpolation('World', 'name', None, ''),))""")
+        ver = {3.13: False, 3.14: True}
+        d = t"Hello { {"name": "Python", "version": ver}!s:z}!"
+        self.assertEqual(pprint.pformat(d, width=1),
+"""\
+Template(strings=('Hello ',
+                  '!'),
+         interpolations=(Interpolation({'name': 'Python',
+                                        'version': {3.13: False,
+                                                    3.14: True}},
+                                       ' '
+                                       '{"name": '
+                                       '"Python", '
+                                       '"version": '
+                                       'ver}',
+                                       's',
+                                       'z'),))""")
+
+    def test_expand_template(self):
+        d = t""
+        self.assertEqual(
+            pprint.pformat(d, expand=True),
+            "Template(strings=('',), interpolations=())",
+        )
+        name = "World"
+        d = t"Hello {name}"
+        self.assertEqual(
+            pprint.pformat(d, width=40, indent=4, expand=True),
+            """\
+Template(
+    strings=('Hello ', ''),
+    interpolations=(
+        Interpolation(
+            value='World',
+            expression='name',
+            conversion=None,
+            format_spec='',
+        ),
+    ),
+)""",
+        )
+        ver = {3.13: False, 3.14: True}
+        d = t"Hello { {"name": "Python", "version": ver}!s:z}!"
+        self.assertEqual(
+            pprint.pformat(d, width=40, indent=4, expand=True),
+            """\
+Template(
+    strings=('Hello ', '!'),
+    interpolations=(
+        Interpolation(
+            value={
+                'name': 'Python',
+                'version': {
+                    3.13: False,
+                    3.14: True,
+                },
+            },
+            expression=' {"name": "Python", '
+            '"version": ver}',
+            conversion='s',
+            format_spec='z',
+        ),
+    ),
+)""",
+        )
+
     def test_expand_dataclass(self):
         @dataclasses.dataclass
         class DummyDataclass:
diff --git a/Misc/NEWS.d/next/Library/2025-05-23-10-28-51.gh-issue-134551.0rnq0X.rst b/Misc/NEWS.d/next/Library/2025-05-23-10-28-51.gh-issue-134551.0rnq0X.rst
new file mode 100644 (file)
index 0000000..94e0c1e
--- /dev/null
@@ -0,0 +1 @@
+Add t-strings support to pprint functions