gh-112632: Add optional keyword-only argument expand to pprint#136964
gh-112632: Add optional keyword-only argument expand to pprint#136964donbarbos wants to merge 51 commits intopython:mainfrom
expand to pprint#136964Conversation
…esting that in the particular unit test)
Co-authored-by: donBarbos <[email protected]>
Co-authored-by: donBarbos <[email protected]>
Co-authored-by: donBarbos <[email protected]>
Co-authored-by: donBarbos <[email protected]>
Co-authored-by: donBarbos <[email protected]>
Co-authored-by: donBarbos <[email protected]>
Co-authored-by: donBarbos <[email protected]>
Co-authored-by: donBarbos <[email protected]>
Co-authored-by: donBarbos <[email protected]>
Co-authored-by: donBarbos <[email protected]>
Co-authored-by: donBarbos <[email protected]>
Co-authored-by: donBarbos <[email protected]>
Co-authored-by: donBarbos <[email protected]>
Co-authored-by: donBarbos <[email protected]>
Co-authored-by: donBarbos <[email protected]>
Co-authored-by: donBarbos <[email protected]>
Co-authored-by: donBarbos <[email protected]>
|
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 Black uses the word "explode", which I'm not sure fits here, but "expand" is similar. And let's update from |
block_style to pprintexpand to pprint
|
Here's a visual test on a bunch of types: scriptimport 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 ---
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 ') |
* Move recursive_indent calculation into helper * Move indent padding into helper
Co-authored-by: Hugo van Kemenade <[email protected]>
|
Would you like to have a go at adding support for |
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 |
|
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 '
)
|
cc @tomasr8 as the previous reviewer (tests coverage problem fixed)
📚 Documentation preview 📚: https://cpython-previews--136964.org.readthedocs.build/