GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — gh-112632: Add optional keyword-only argument `expand` to `pprint` by donbarbos · Pull Request #136964 · python/cpython

Conversation

@donbarbos

@donbarbos donbarbos commented Jul 22, 2025 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

cc @tomasr8 as the previous reviewer (tests coverage problem fixed)

  • Issue: pprint with compact indent #112632

📚 Documentation preview 📚: https://cpython-previews--136964.org.readthedocs.build/

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

StefanTodoran reacted with thumbs up emoji
All reactions
  • 👍 1 reaction
stodoran and others added 30 commits January 24, 2025 18:19
@stodoran
Added an option for block formatting to pprint
b9baf94
@StefanTodoran
Small bug fix for indent=1, added to unit test
f5fcbfc
@StefanTodoran
Merge branch 'main' into fix-issue-112632
31a4d1e
@StefanTodoran
Remove set from block style unit test (since order kept changing)
a92ef3d
@blurb-it
📜🤖 Added by blurb_it.
d9a147f
@StefanTodoran
Merge branch 'main' into fix-issue-112632
ffef3b0
@StefanTodoran
Fix params in news entry
19e4e08
@StefanTodoran
Fix line length for news entry
8ef085f
@StefanTodoran
Shorten news entry
c446aa1
@StefanTodoran
Merge branch 'main' into fix-issue-112632
f9bd6ef
@StefanTodoran
Address documentation related PR comments
49b1108
@StefanTodoran
Merge branch 'main' into fix-issue-112632
62dd5e5
@StefanTodoran
Fix length of title underline :/
0b8fd2b
@StefanTodoran
Fix test case, remove unnecessary recursion on dataclass (we aren't t…
5f08960
…esting that in the particular unit test)
@StefanTodoran
Merge branch 'main' into fix-issue-112632
ac71fc4
@StefanTodoran @donbarbos
Update Doc/library/pprint.rst
59ed5fd
Co-authored-by: donBarbos <[email protected]>
@StefanTodoran @donbarbos
Update Doc/library/pprint.rst
cbc392d
Co-authored-by: donBarbos <[email protected]>
@StefanTodoran @donbarbos
Update Doc/library/pprint.rst
d1af62c
Co-authored-by: donBarbos <[email protected]>
@StefanTodoran @donbarbos
Update Doc/library/pprint.rst
283ed38
Co-authored-by: donBarbos <[email protected]>
@StefanTodoran @donbarbos
Update Doc/library/pprint.rst
142b92b
Co-authored-by: donBarbos <[email protected]>
@StefanTodoran @donbarbos
Update Doc/whatsnew/3.14.rst
2273be2
Co-authored-by: donBarbos <[email protected]>
@StefanTodoran @donbarbos
Update Lib/pprint.py
d8b5942
Co-authored-by: donBarbos <[email protected]>
@StefanTodoran @donbarbos
Update Lib/pprint.py
8c3ed5c
Co-authored-by: donBarbos <[email protected]>
@StefanTodoran @donbarbos
Update Lib/pprint.py
9c7afd5
Co-authored-by: donBarbos <[email protected]>
@StefanTodoran @donbarbos
Update Lib/pprint.py
4e7fbff
Co-authored-by: donBarbos <[email protected]>
@StefanTodoran @donbarbos
Update Lib/pprint.py
5abab85
Co-authored-by: donBarbos <[email protected]>
@StefanTodoran @donbarbos
Update Lib/pprint.py
5e8a624
Co-authored-by: donBarbos <[email protected]>
@StefanTodoran @donbarbos
Update Lib/test/test_pprint.py
5ffbd0d
Co-authored-by: donBarbos <[email protected]>
@StefanTodoran @donbarbos
Update Lib/test/test_pprint.py
fa4cdac
Co-authored-by: donBarbos <[email protected]>
@StefanTodoran @donbarbos
Update Lib/test/test_pprint.py
6bffc7e
Co-authored-by: donBarbos <[email protected]>
donbarbos added 2 commits July 22, 2025 07:35
@donbarbos
Merge branch 'main' into issue-112632
fa0329b
@donbarbos
Move to new whatsnew entry
ed2fcda
@hugovk hugovk mentioned this pull request Mar 24, 2026
pprint: Rename block_style to expand donbarbos/cpython#1
Merged
@hugovk

hugovk commented Mar 24, 2026

Copy link
Copy Markdown
Member

Thanks for working on this, it's looking good!

Is "block style JSON formatting" an established term? Wondering if there's a better explanation. Maybe just "pretty-printed JSON" is better?

I've also opened donbarbos#1 to suggest renaming block_style to expand, as it mirrors compact well.

Black uses the word "explode", which I'm not sure fits here, but "expand" is similar.

And let's update from main after merging donbarbos#1, it's been a while since this ran CI.

donbarbos reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@hugovk
Rename block_style to expand (#1)
af663a8
@donbarbos
donbarbos requested a review from AA-Turner as a code owner March 25, 2026 18:43
@donbarbos
Merge branch 'main' into issue-112632
9302ad4
@hugovk hugovk changed the title gh-112632: Add optional keyword-only argument block_style to pprint gh-112632: Add optional keyword-only argument expand to pprint Mar 25, 2026
hugovk
hugovk reviewed Mar 27, 2026
View reviewed changes

@hugovk hugovk left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And see also donbarbos#2.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Doc/library/pprint.rst Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Doc/library/pprint.rst Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Doc/whatsnew/3.15.rst Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Lib/pprint.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

@hugovk

hugovk commented Mar 27, 2026

Copy link
Copy Markdown
Member

Here's a visual test on a bunch of types:

script
import collections
import dataclasses
import pprint
import types

pp = lambda label, obj: print(
    f"--- {label} ---\n{pprint.pformat(obj, width=20, indent=4, expand=True)}\n"
)

pp("dict", {"foo": "bar", "baz": 123, "qux": [1, 2, 3], "quux": {"a": "b"}})

pp("list", ["foo", "bar", "baz", "qux", "quux"])

pp("tuple", ("foo", "bar", "baz", 4, 5, 6))

pp("tuple (single)", ("only",))

pp("set", {"foo", "bar", "baz", "qux", (1, 2, 3)})

pp("frozenset", frozenset({"foo", "bar", "baz", (1, 2, 3)}))

pp("OrderedDict", collections.OrderedDict([("foo", 1), ("bar", 12), ("baz", 123)]))

dd = collections.defaultdict(list)
dd["foo"].extend(["bar", "baz", "qux"])
dd["bar"] = {"a": "b", "c": None}
pp("defaultdict", dd)

pp("Counter", collections.Counter("abcdeabcdabcaba"))

pp("ChainMap", collections.ChainMap({"foo": "bar"}, {"baz": "qux"}, {"a": [1, 2, 3]}))

pp("deque", collections.deque(["foo", 123, {"a": "b"}, [1, 2, 3]]))

pp("deque (maxlen)", collections.deque(["foo", 123, {"a": "b"}], maxlen=10))


@dataclasses.dataclass
class Point:
    x: float
    y: float
    label: str
    tags: list = dataclasses.field(default_factory=list)


pp("dataclass", Point(1.0, 2.5, "origin", ["a", "b", "c"]))

pp(
    "SimpleNamespace",
    types.SimpleNamespace(foo="bar", count=42, nested=types.SimpleNamespace(x=1, y=2)),
)

pp("bytes", b"Hello world! foo bar baz 123 456 789")

pp("bytearray", bytearray(b"Hello world! foo bar baz 123 456 789"))

pp("mappingproxy", types.MappingProxyType({"foo": "bar", "baz": 123, "qux": [1, 2]}))

pp("frozendict", frozendict({"foo": "bar", "baz": 123, "qux": [1, 2]}))

pp("dict_keys", {"foo": 1, "bar": 2, "baz": 3, "qux": 4, "quux": 5}.keys())

pp("dict_values", {"foo": 1, "bar": 2, "baz": 3, "qux": 4, "quux": 5}.values())

pp("dict_items", {"foo": 1, "bar": 2, "baz": 3, "qux": 4, "quux": 5}.items())

pp("str", "The quick brown fox jumped over the lazy dog " * 3)

pp("UserDict", collections.UserDict({"foo": "bar", "baz": 123, "qux": [1, 2]}))

pp("UserList", collections.UserList(["foo", "bar", "baz", "qux", "quux"]))

pp(
    "UserString",
    collections.UserString("The quick brown fox jumped over the lazy dog " * 3),
)

The new frozendict, other dict_* and str need updating to support expand:

--- frozendict ---
frozendict({
               'baz': 123,
               'foo': 'bar',
               'qux': [
                   1,
                   2
               ]
           })

--- dict_keys ---
dict_keys([       'bar',
    'baz',
    'foo',
    'quux',
    'qux'])

--- dict_values ---
dict_values([       1,
    2,
    3,
    4,
    5])

--- dict_items ---
dict_items([       ('bar', 2),
    ('baz', 3),
    ('foo', 1),
    ('quux', 5),
    ('qux', 4)])

--- str ---
('The quick brown '
 'fox jumped over '
 'the lazy dog The '
 'quick brown fox '
 'jumped over the '
 'lazy dog The '
 'quick brown fox '
 'jumped over the '
 'lazy dog ')
Full output
--- dict ---
{
    'baz': 123,
    'foo': 'bar',
    'quux': {'a': 'b'},
    'qux': [1, 2, 3]
}

--- list ---
[
    'foo',
    'bar',
    'baz',
    'qux',
    'quux'
]

--- tuple ---
(
    'foo',
    'bar',
    'baz',
    4,
    5,
    6
)

--- tuple (single) ---
('only',)

--- set ---
{
    'bar',
    'baz',
    'foo',
    'qux',
    (1, 2, 3)
}

--- frozenset ---
frozenset({
    'bar',
    'baz',
    'foo',
    (1, 2, 3)
})

--- OrderedDict ---
OrderedDict([
    ('foo', 1),
    ('bar', 12),
    ('baz', 123)
])

--- defaultdict ---
defaultdict(<class 'list'>, {
    'bar': {
        'a': 'b',
        'c': None
    },
    'foo': [
        'bar',
        'baz',
        'qux'
    ]
})

--- Counter ---
Counter({
    'a': 5,
    'b': 4,
    'c': 3,
    'd': 2,
    'e': 1
})

--- ChainMap ---
ChainMap(
    {'foo': 'bar'},
    {'baz': 'qux'},
    {
        'a': [1, 2, 3]
    }
)

--- deque ---
deque([
    'foo',
    123,
    {'a': 'b'},
    [1, 2, 3]
])

--- deque (maxlen) ---
deque([
    'foo',
    123,
    {'a': 'b'}
], maxlen=10)

--- dataclass ---
Point(
    x=1.0,
    y=2.5,
    label='origin',
    tags=['a', 'b', 'c']
)

--- SimpleNamespace ---
namespace(
    foo='bar',
    count=42,
    nested=namespace(
        x=1,
        y=2
    )
)

--- bytes ---
(
    b'Hello world!'
    b' foo bar baz'
    b' 123 456 789'
)

--- bytearray ---
bytearray(
    b'Hello world!'
    b' foo bar baz'
    b' 123 456 789'
)

--- mappingproxy ---
mappingproxy({
    'baz': 123,
    'foo': 'bar',
    'qux': [1, 2]
})

--- frozendict ---
frozendict({
               'baz': 123,
               'foo': 'bar',
               'qux': [
                   1,
                   2
               ]
           })

--- dict_keys ---
dict_keys([       'bar',
    'baz',
    'foo',
    'quux',
    'qux'])

--- dict_values ---
dict_values([       1,
    2,
    3,
    4,
    5])

--- dict_items ---
dict_items([       ('bar', 2),
    ('baz', 3),
    ('foo', 1),
    ('quux', 5),
    ('qux', 4)])

--- str ---
('The quick brown '
 'fox jumped over '
 'the lazy dog The '
 'quick brown fox '
 'jumped over the '
 'lazy dog The '
 'quick brown fox '
 'jumped over the '
 'lazy dog ')

--- UserDict ---
{
    'baz': 123,
    'foo': 'bar',
    'qux': [1, 2]
}

--- UserList ---
[
    'foo',
    'bar',
    'baz',
    'qux',
    'quux'
]

--- UserString ---
('The quick brown '
 'fox jumped over '
 'the lazy dog The '
 'quick brown fox '
 'jumped over the '
 'lazy dog The '
 'quick brown fox '
 'jumped over the '
 'lazy dog ')
donbarbos reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

hugovk and others added 2 commits March 27, 2026 14:37
@hugovk
Move calculations into helpers (#2)
1ca9963
* Move recursive_indent calculation into helper
* Move indent padding into helper
@donbarbos @hugovk
Apply suggestions from code review
c6a6c1a
Co-authored-by: Hugo van Kemenade <[email protected]>
@hugovk

hugovk commented Mar 28, 2026

Copy link
Copy Markdown
Member

Would you like to have a go at adding support for frozendict, dict_* and str or shall I have a look?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@hugovk hugovk mentioned this pull request Mar 28, 2026
gh-112632 : Added an option for block formatting to pprint #129274
Closed
@donbarbos

donbarbos commented Mar 28, 2026

Copy link
Copy Markdown
Contributor Author

Would you like to have a go at adding support for frozendict, dict_* and str or shall I have a look?

I'd like to do it myself, but I don't think I'll be able to devote enough time to it in the near future. So I'd be grateful for help

hugovk reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

hugovk added 4 commits March 28, 2026 21:13
@hugovk
Implement expand=True for frozendict
64238cd
@hugovk
Implement expand=True for dict views
b1df0bb
@hugovk
Implement expand=True for str
c3dfaab
@hugovk
Add trailing comma when expanded
8f48ddb
@hugovk

hugovk commented Mar 29, 2026

Copy link
Copy Markdown
Member

I've also added a trailing comma when expanded, similar to modern Black/Ruff style:

Full output
--- dict ---
{
 'baz': 123,
 'foo': 'bar',
 'quux': {'a': 'b'},
 'qux': [1, 2, 3],
}

--- list ---
[
 'foo',
 'bar',
 'baz',
 'qux',
 'quux',
]

--- tuple ---
(
 'foo',
 'bar',
 'baz',
 4,
 5,
 6,
)

--- tuple (single) ---
('only',)

--- set ---
{
 'bar',
 'baz',
 'foo',
 'qux',
 (1, 2, 3),
}

--- frozenset ---
frozenset({
 'bar',
 'baz',
 'foo',
 (1, 2, 3),
})

--- OrderedDict ---
OrderedDict([
 ('foo', 1),
 ('bar', 12),
 ('baz', 123),
])

--- defaultdict ---
defaultdict(<class 'list'>, {
 'bar': {
  'a': 'b',
  'c': None,
 },
 'foo': [
  'bar',
  'baz',
  'qux',
 ],
})

--- Counter ---
Counter({
 'a': 5,
 'b': 4,
 'c': 3,
 'd': 2,
 'e': 1,
})

--- ChainMap ---
ChainMap(
 {'foo': 'bar'},
 {'baz': 'qux'},
 {'a': [1, 2, 3]},
)

--- deque ---
deque([
 'foo',
 123,
 {'a': 'b'},
 [1, 2, 3],
])

--- deque (maxlen) ---
deque([
 'foo',
 123,
 {'a': 'b'},
], maxlen=10)

--- dataclass ---
Point(
 x=1.0,
 y=2.5,
 label='origin',
 tags=['a', 'b', 'c'],
)

--- SimpleNamespace ---
namespace(
 foo='bar',
 count=42,
 nested=namespace(x=1, y=2),
)

--- bytes ---
(
 b'Hello world! foo'
 b' bar baz 123 456'
 b' 789'
)

--- bytearray ---
bytearray(
 b'Hello world! foo'
 b' bar baz 123 456'
 b' 789'
)

--- mappingproxy ---
mappingproxy({
 'baz': 123,
 'foo': 'bar',
 'qux': [1, 2],
})

--- frozendict ---
frozendict({
 'baz': 123,
 'foo': 'bar',
 'qux': [1, 2],
})

--- dict_keys ---
dict_keys([
 'bar',
 'baz',
 'foo',
 'quux',
 'qux',
])

--- dict_values ---
dict_values([
 1,
 2,
 3,
 4,
 5,
])

--- dict_items ---
dict_items([
 ('bar', 2),
 ('baz', 3),
 ('foo', 1),
 ('quux', 5),
 ('qux', 4),
])

--- str ---
(
 'The quick brown '
 'fox jumped over '
 'the lazy dog The '
 'quick brown fox '
 'jumped over the '
 'lazy dog The '
 'quick brown fox '
 'jumped over the '
 'lazy dog '
)

--- UserDict ---
{
 'baz': 123,
 'foo': 'bar',
 'qux': [1, 2],
}

--- UserList ---
[
 'foo',
 'bar',
 'baz',
 'qux',
 'quux',
]

--- UserString ---
(
 'The quick brown '
 'fox jumped over '
 'the lazy dog The '
 'quick brown fox '
 'jumped over the '
 'lazy dog The '
 'quick brown fox '
 'jumped over the '
 'lazy dog '
)
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@hugovk
Update docs
24d4893
hugovk
hugovk approved these changes Mar 29, 2026
View reviewed changes
@bedevere-app bedevere-app Bot added awaiting merge and removed awaiting review labels Mar 29, 2026
@hugovk
hugovk merged commit 132abfd into python:main Apr 7, 2026
52 checks passed

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-app bedevere-app Bot removed the awaiting merge label Apr 7, 2026
@hugovk

hugovk commented Apr 7, 2026

Copy link
Copy Markdown
Member

Thank you!

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@donbarbos

donbarbos commented Apr 7, 2026

Copy link
Copy Markdown
Contributor Author

Big thanks!

hugovk reacted with rocket emoji
All reactions
  • 🚀 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@hugovk hugovk mentioned this pull request Apr 13, 2026
gh-134551: Add t-strings support to pprint #134577
Merged
ljfp pushed a commit to ljfp/cpython that referenced this pull request Apr 25, 2026
@donbarbos @stodoran
@StefanTodoran @blurb-it @hugovk @ljfp
pythongh-112632: Add optional keyword-only argument expand to `ppri…
d4ee80b
…nt` (python#136964)

Co-authored-by: stodoran <[email protected]>
Co-authored-by: StefanTodoran <[email protected]>
Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
Co-authored-by: Hugo van Kemenade <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@hugovk hugovk hugovk approved these changes
@AA-Turner AA-Turner Awaiting requested review from AA-Turner AA-Turner is a code owner

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

4 participants

@donbarbos @hugovk @stodoran @StefanTodoran
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.