Skip to content
Merged
Show file tree
Hide file tree
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
6 changes: 5 additions & 1 deletion Doc/whatsnew/3.15.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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_*
Expand Down
55 changes: 55 additions & 0 deletions Lib/pprint.py
Original file line number Diff line number Diff line change
Expand Up @@ -735,6 +735,61 @@ def _pprint_user_string(self, object, stream, indent, allowance, context, level)

_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)
Expand Down
80 changes: 80 additions & 0 deletions Lib/test/test_pprint.py
Original file line number Diff line number Diff line change
Expand Up @@ -1515,6 +1515,86 @@ def test_user_string(self):
'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:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add t-strings support to pprint functions
Loading