Skip to content

gh-112632: Add optional keyword-only argument block_style to pprint #136964

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 42 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
b9baf94
Added an option for block formatting to pprint
stodoran Jan 25, 2025
f5fcbfc
Small bug fix for indent=1, added to unit test
StefanTodoran Feb 6, 2025
31a4d1e
Merge branch 'main' into fix-issue-112632
StefanTodoran Feb 6, 2025
a92ef3d
Remove set from block style unit test (since order kept changing)
StefanTodoran Feb 7, 2025
d9a147f
📜🤖 Added by blurb_it.
blurb-it[bot] Feb 7, 2025
ffef3b0
Merge branch 'main' into fix-issue-112632
StefanTodoran Feb 7, 2025
19e4e08
Fix params in news entry
StefanTodoran Feb 7, 2025
8ef085f
Fix line length for news entry
StefanTodoran Feb 7, 2025
c446aa1
Shorten news entry
StefanTodoran Feb 7, 2025
f9bd6ef
Merge branch 'main' into fix-issue-112632
StefanTodoran Feb 9, 2025
49b1108
Address documentation related PR comments
StefanTodoran Feb 19, 2025
62dd5e5
Merge branch 'main' into fix-issue-112632
StefanTodoran Feb 19, 2025
0b8fd2b
Fix length of title underline :/
StefanTodoran Feb 19, 2025
5f08960
Fix test case, remove unnecessary recursion on dataclass (we aren't t…
StefanTodoran Feb 19, 2025
ac71fc4
Merge branch 'main' into fix-issue-112632
StefanTodoran Feb 25, 2025
59ed5fd
Update Doc/library/pprint.rst
StefanTodoran Feb 25, 2025
cbc392d
Update Doc/library/pprint.rst
StefanTodoran Feb 25, 2025
d1af62c
Update Doc/library/pprint.rst
StefanTodoran Feb 25, 2025
283ed38
Update Doc/library/pprint.rst
StefanTodoran Feb 25, 2025
142b92b
Update Doc/library/pprint.rst
StefanTodoran Feb 25, 2025
2273be2
Update Doc/whatsnew/3.14.rst
StefanTodoran Feb 25, 2025
d8b5942
Update Lib/pprint.py
StefanTodoran Feb 25, 2025
8c3ed5c
Update Lib/pprint.py
StefanTodoran Feb 25, 2025
9c7afd5
Update Lib/pprint.py
StefanTodoran Feb 25, 2025
4e7fbff
Update Lib/pprint.py
StefanTodoran Feb 25, 2025
5abab85
Update Lib/pprint.py
StefanTodoran Feb 25, 2025
5e8a624
Update Lib/pprint.py
StefanTodoran Feb 25, 2025
5ffbd0d
Update Lib/test/test_pprint.py
StefanTodoran Feb 25, 2025
fa4cdac
Update Lib/test/test_pprint.py
StefanTodoran Feb 25, 2025
6bffc7e
Update Lib/test/test_pprint.py
StefanTodoran Feb 25, 2025
c8ce4ff
Update Lib/test/test_pprint.py
StefanTodoran Feb 25, 2025
879f1da
Update Lib/test/test_pprint.py
StefanTodoran Feb 25, 2025
21c9fa6
Update Lib/test/test_pprint.py
StefanTodoran Feb 25, 2025
815e1da
Update Lib/test/test_pprint.py
StefanTodoran Feb 25, 2025
9d12a8a
Merge branch 'main' into fix-issue-112632
StefanTodoran Feb 25, 2025
a7c26dd
Apply suggestions from code review
StefanTodoran Feb 25, 2025
37312d9
Split large test case into multiple smaller ones, update news entry
StefanTodoran Mar 28, 2025
e3b09fa
Merge branch 'main' into fix-issue-112632
StefanTodoran Mar 28, 2025
712b644
Merge changes
StefanTodoran Mar 28, 2025
6425c4a
Accept suggestions
donBarbos Jul 22, 2025
fa0329b
Merge branch 'main' into issue-112632
donBarbos Jul 22, 2025
ed2fcda
Move to new whatsnew entry
donBarbos Jul 22, 2025
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
16 changes: 10 additions & 6 deletions Doc/library/pprint.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ Functions
---------

.. function:: pp(object, stream=None, indent=1, width=80, depth=None, *, \
compact=False, sort_dicts=False, underscore_numbers=False, block_style=False)
compact=False, sort_dicts=False, underscore_numbers=False, \
block_style=False)

Prints the formatted representation of *object*, followed by a newline.
This function may be used in the interactive interpreter
Expand Down Expand Up @@ -106,15 +107,17 @@ Functions


.. function:: pprint(object, stream=None, indent=1, width=80, depth=None, *, \
compact=False, sort_dicts=True, underscore_numbers=False, block_style=False)
compact=False, sort_dicts=True, \
underscore_numbers=False, block_style=False)

Alias for :func:`~pprint.pp` with *sort_dicts* set to ``True`` by default,
which would automatically sort the dictionaries' keys,
you might want to use :func:`~pprint.pp` instead where it is ``False`` by default.


.. function:: pformat(object, indent=1, width=80, depth=None, *, \
compact=False, sort_dicts=True, underscore_numbers=False, block_style=False)
compact=False, sort_dicts=True, \
underscore_numbers=False, block_style=False)

Return the formatted representation of *object* as a string. *indent*,
*width*, *depth*, *compact*, *sort_dicts*, *underscore_numbers* and *block_style* are
Expand Down Expand Up @@ -161,7 +164,8 @@ PrettyPrinter Objects
.. index:: single: ...; placeholder

.. class:: PrettyPrinter(indent=1, width=80, depth=None, stream=None, *, \
compact=False, sort_dicts=True, underscore_numbers=False, block_style=False)
compact=False, sort_dicts=True, \
underscore_numbers=False, block_style=False)

Construct a :class:`PrettyPrinter` instance.

Expand Down Expand Up @@ -446,8 +450,8 @@ cannot be split, the specified width will be exceeded::
'summary': 'A sample Python project',
'version': '1.2.0'}

Lastly, we can achieve block style formatting with the *block_style* parameter. Best results
are achieved with a higher *indent* value::
Lastly, we can achieve block style formatting with the *block_style* parameter.
Best results are achieved with a higher *indent* value::

>>> pprint.pp(project_info, indent=4, block_style=True)
{
Expand Down
4 changes: 2 additions & 2 deletions Doc/whatsnew/3.14.rst
Original file line number Diff line number Diff line change
Expand Up @@ -894,7 +894,7 @@ pprint
* Add a *block_style* keyword argument for :func:`pprint.pprint`,
:func:`pprint.pformat`, :func:`pprint.pp`. If true, the output will be
formatted in a block style similar to pretty-printed :func:`json.dumps` when
*indent* is supplied. Incompatible with *compact* mode.
*indent* is supplied.
(Contributed by Stefan Todoran in :gh:`129274`.)


Expand Down Expand Up @@ -1210,7 +1210,7 @@ Deprecated
.. include:: ../deprecations/pending-removal-in-future.rst

Removed
=======
========

argparse
--------
Expand Down
16 changes: 10 additions & 6 deletions Lib/pprint.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@


def pprint(object, stream=None, indent=1, width=80, depth=None, *,
compact=False, sort_dicts=True, underscore_numbers=False, block_style=False):
compact=False, sort_dicts=True, underscore_numbers=False,
block_style=False):
"""Pretty-print a Python object to a stream [default is sys.stdout]."""
printer = PrettyPrinter(
stream=stream, indent=indent, width=width, depth=depth,
Expand All @@ -54,11 +55,13 @@ def pprint(object, stream=None, indent=1, width=80, depth=None, *,


def pformat(object, indent=1, width=80, depth=None, *,
compact=False, sort_dicts=True, underscore_numbers=False, block_style=False):
compact=False, sort_dicts=True, underscore_numbers=False,
block_style=False):
"""Format a Python object into a pretty-printed representation."""
return PrettyPrinter(indent=indent, width=width, depth=depth,
compact=compact, sort_dicts=sort_dicts,
underscore_numbers=underscore_numbers, block_style=block_style).pformat(object)
underscore_numbers=underscore_numbers,
block_style=block_style).pformat(object)


def pp(object, *args, sort_dicts=False, **kwargs):
Expand Down Expand Up @@ -111,7 +114,8 @@ def _safe_tuple(t):

class PrettyPrinter:
def __init__(self, indent=1, width=80, depth=None, stream=None, *,
compact=False, sort_dicts=True, underscore_numbers=False, block_style=False):
compact=False, sort_dicts=True, underscore_numbers=False,
block_style=False):
"""Handle pretty printing operations onto a stream using a set of
configured parameters.

Expand Down Expand Up @@ -215,13 +219,13 @@ def _format(self, object, stream, indent, allowance, context, level):

def _format_block_start(self, start_str, indent):
if self._block_style:
return start_str +'\n' + ' ' * indent
return f"{start_str}\n{' ' * indent}"
else:
return start_str

def _format_block_end(self, end_str, indent):
if self._block_style:
return '\n' + ' ' * indent + end_str
return f"\n{' ' * indent}{end_str}"
else:
return end_str

Expand Down
50 changes: 19 additions & 31 deletions Lib/test/test_pprint.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,6 @@
import re
import types
import unittest
from collections import OrderedDict
from collections import defaultdict
from collections import Counter
from collections import ChainMap
from collections import deque
from collections import UserDict, UserList
from dataclasses import dataclass, field
from types import SimpleNamespace, MappingProxyType

# list, tuple and dict subclasses that do or don't overwrite __repr__
class list2(list):
Expand Down Expand Up @@ -1133,13 +1125,13 @@ def test_user_string(self):
'lazy dog'}""")

def test_block_style_dataclass(self):
@dataclass
@dataclasses.dataclass
class DummyDataclass:
foo: str
bar: float
baz: bool
qux: dict = field(default_factory=dict)
quux: list = field(default_factory=list)
qux: dict = dataclasses.field(default_factory=dict)
quux: list = dataclasses.field(default_factory=list)
corge: int = 1
garply: tuple = (1, 2, 3, 4)
dummy_dataclass = DummyDataclass(
Expand Down Expand Up @@ -1182,7 +1174,7 @@ def test_block_style_dict(self):
}""")

def test_block_style_ordered_dict(self):
dummy_ordered_dict = OrderedDict(
dummy_ordered_dict = collections.OrderedDict(
[
("foo", 1),
("bar", 12),
Expand Down Expand Up @@ -1302,7 +1294,7 @@ def test_block_style_mappingproxy(self):
"quux": ["foo", "bar", "baz"],
"corge": 7,
}
dummy_mappingproxy = MappingProxyType(dummy_dict)
dummy_mappingproxy = types.MappingProxyType(dummy_dict)
self.assertEqual(pprint.pformat(dummy_mappingproxy, width=40, indent=4, block_style=True),
"""\
mappingproxy({
Expand All @@ -1314,10 +1306,10 @@ def test_block_style_mappingproxy(self):
})""")

def test_block_style_namespace(self):
dummy_namespace = SimpleNamespace(
dummy_namespace = types.SimpleNamespace(
foo="bar",
bar=42,
baz=SimpleNamespace(
baz=types.SimpleNamespace(
x=321,
y="string",
d={"foo": True, "bar": "baz"},
Expand All @@ -1337,7 +1329,7 @@ def test_block_style_namespace(self):
)""")

def test_block_style_defaultdict(self):
dummy_defaultdict = defaultdict(list)
dummy_defaultdict = collections.defaultdict(list)
dummy_defaultdict["foo"].append("bar")
dummy_defaultdict["foo"].append("baz")
dummy_defaultdict["foo"].append("qux")
Expand All @@ -1350,7 +1342,7 @@ def test_block_style_defaultdict(self):
})""")

def test_block_style_counter(self):
dummy_counter = Counter("abcdeabcdabcaba")
dummy_counter = collections.Counter("abcdeabcdabcaba")
expected = """\
Counter({
'a': 5,
Expand Down Expand Up @@ -1379,7 +1371,7 @@ def test_block_style_chainmap(self):
"quux": ["foo", "bar", "baz"],
"corge": 7,
}
dummy_chainmap = ChainMap(
dummy_chainmap = collections.ChainMap(
{"foo": "bar"},
{"baz": "qux"},
{"corge": dummy_dict},
Expand Down Expand Up @@ -1421,7 +1413,7 @@ def test_block_style_deque(self):
dummy_set = {
(1, 2, 3),
}
dummy_deque = deque(maxlen=10)
dummy_deque = collections.deque(maxlen=10)
dummy_deque.append("foo")
dummy_deque.append(123)
dummy_deque.append(dummy_dict)
Expand All @@ -1446,21 +1438,16 @@ def test_block_style_deque(self):
], maxlen=10)""")

def test_block_style_userdict(self):
class DummyUserDict(UserDict):
class DummyUserDict(collections.UserDict):
"""A custom UserDict with some extra attributes"""

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.access_count = 0
dummy_userdict = DummyUserDict(
{
"foo": "bar",
"baz": 123,
"qux": {"foo": "bar", "baz": 123},
"quux": ["foo", "bar", "baz"],
"corge": 7,
}
)
dummy_userdict = DummyUserDict({ "foo": "bar", "baz": 123,
"qux": {"foo": "bar", "baz": 123},
"quux": ["foo", "bar", "baz"],
"corge": 7 })
dummy_userdict.access_count = 5

self.assertEqual(pprint.pformat(dummy_userdict, width=40, indent=4, block_style=True),
Expand All @@ -1474,13 +1461,14 @@ def __init__(self, *args, **kwargs):
}""")

def test_block_style_userlist(self):
class DummyUserList(UserList):
class DummyUserList(collections.UserList):
"""A custom UserList with some extra attributes"""

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.description = "foo"
dummy_userlist = DummyUserList(["first", 2, {"key": "value"}, [4, 5, 6]])
dummy_userlist = DummyUserList(["first", 2, {"key": "value"},
[4, 5, 6]])

self.assertEqual(pprint.pformat(dummy_userlist, width=40, indent=4, block_style=True),
"""\
Expand Down
Loading
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy