gh-112632 : Added an option for block formatting to pprint#129274
gh-112632 : Added an option for block formatting to pprint#129274StefanTodoran wants to merge 39 commits intopython:mainfrom
pprint#129274Conversation
|
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
|
looks pretty good 👍, but
And please try to make sure CI passes |
|
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
|
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
|
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
|
Could you also add a News entry into the And I think it's a full fledged new feature so this update deserves to be in |
|
I've added a test case for the new
|
sometimes the problem may not be in you and you need to wait and update your branch (at least it helped me) |
Misc/NEWS.d/next/Library/2025-02-07-00-48-07.gh-issue-112632.95MM0C.rst
Outdated
Show resolved
Hide resolved
|
and don't forget to add news to
|
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]>
|
I've merged those changes. Thanks for helping me out with that! Is there anything else? |
Let's try to solve problems with |
Co-authored-by: donBarbos <[email protected]>
|
I think we can ping @tomasr8 if you're done making changes. |
|
Sounds good, I have no more changes to add. |
tomasr8
left a comment
There was a problem hiding this comment.
I think it's looking pretty good now! Just two comments:
| stream.write(cls.__name__ + '({') | ||
| if self._indent_per_level > 1: | ||
| stream.write(self._format_block_start(cls.__name__ + '({', indent)) | ||
| if self._indent_per_level > 1 and not self._block_style: |
There was a problem hiding this comment.
This is not covered by tests (the condition is always False).
For such a large change, I suggest running coverage and checking the html report to make sure your tests cover all cases. There's a guide here, but the gist is:
./python -m ensurepip
./python -m pip install coverage
./python -m coverage run --pylib --source=pprint Lib/test/regrtest.py test_pprint
./python -m coverage html -i --include=`pwd`/Lib/* --omit="Lib/test/*,Lib/*/tests/*"
There was a problem hiding this comment.
I don't understand, what do you mean the case is not covered? The existing tests already covered the case where _block_style is False and _indent_per_level is >1.
Also when I run the coverage command I don't see anything missing, am I doing something wrong?
python3 -m coverage run --pylib --source=pprint Lib/test/regrtest.py test_pprint
/Users/stodoran/Desktop/cpython/venv/lib/python3.13/site-packages/coverage/inorout.py:486: CoverageWarning: Already imported a file that will be measured: /opt/homebrew/Cellar/[email protected]/3.13.2/Frameworks/Python.framework/Versions/3.13/lib/python3.13/pprint.py (already-imported)
self.warn(msg, slug="already-imported")
Using random seed: 4261013096
0:00:00 load avg: 4.87 Run 1 test sequentially in a single process
0:00:00 load avg: 4.87 [1/1] test_pprint
== Tests result: SUCCESS ==
1 test OK.
Total duration: 129 ms
Total tests: run=44
Total test files: run=1/1
Result: SUCCESS
python3 -m coverage html -i --include=`pwd`/Lib/* --omit="Lib/test/*,Lib/*/tests/*"
No data to report.
There was a problem hiding this comment.
@StefanTodoran if you can't get HTML-based report you can use cli:
$ ./python -m coverage report --show-missing
Name Stmts Miss Branch BrPart Cover Missing
-----------------------------------------------------------
Lib/pprint.py 476 81 182 7 87% 37-46, 57, 67-72, 77, 82, 87-99, 102, 110, 115-116, 172, 174-177, 182, 185, 189, 192-195, 220, 226, 232, 243-245, 262-264, 276-278, 284-286, 293-295, 312-315, 353->326, 367-369, 388-390, 400-402, 409-411, 424-426, 444, 464, 507, 513, 516, 523, 537-539, 546, 556-558, 560-561, 573-575, 595-597, 600-602, 605-607, 610-612, 694, 703, 717->exit
-----------------------------------------------------------
TOTAL 476 81 182 7 87%I don't know why on the main branch this line is shown as covered, but this can be solved by adding an explicit pass of indent>1 to the QueryTestCase.test_counter test, like this:
d = collections.Counter('senselessness')
self.assertEqual(pprint.pformat(d, indent=2, width=1),
"""\
Counter({ 's': 6,
'e': 4,
'n': 2,
'l': 1})""")and the line will become covered 👍
(unfortunately i can't send you a suggestion as there is no diff nearby, so please add it yourself)
| stream.write('[') | ||
| stream.write(self._format_block_start('[', indent)) | ||
| self._format_items(object, stream, indent, allowance + 1, | ||
| context, level) | ||
| stream.write(']') | ||
| stream.write(self._format_block_end(']', indent)) |
There was a problem hiding this comment.
You have a lot of repeated code here conditional on self._block_style. How about defining a context manager to clean this up?
with self._block(stream, indent, '[', ']') as new_indent:
self._format_items(object, stream, new_indent, allowance + 1,
context, level)pprint
| compact=False, sort_dicts=False, underscore_numbers=False, \ | ||
| block_style=False) |
There was a problem hiding this comment.
These are keyword-only (after *), so we have the luxury of alphabetical sorting:
| compact=False, sort_dicts=False, underscore_numbers=False, \ | |
| block_style=False) | |
| block_style=False, compact=False, sort_dicts=False, \ | |
| underscore_numbers=False) |
| compact=False, sort_dicts=True, \ | ||
| underscore_numbers=False, block_style=False) |
There was a problem hiding this comment.
Likewise
| compact=False, sort_dicts=True, \ | |
| underscore_numbers=False, block_style=False) | |
| block_style=False, compact=False, \ | |
| sort_dicts=True, underscore_numbers=False) |
| If ``True``, | ||
| opening parentheses and brackets will be followed by a newline and the | ||
| following content will be indented by one level, similar to block style | ||
| JSON formatting. This option is not compatible with *compact*. |
There was a problem hiding this comment.
This option is not compatible with compact.
A passing thought: Perhaps introduce a mode (str) argument, and deprecate compact in favour of it? It's not great to have two conflicting Booleans, though it may be the best option for now.
| compact=False, sort_dicts=True, \ | ||
| underscore_numbers=False, block_style=False) |
There was a problem hiding this comment.
Likewise
| compact=False, sort_dicts=True, \ | |
| underscore_numbers=False, block_style=False) | |
| block_style=False, compact=False, \ | |
| sort_dicts=True, underscore_numbers=False) |
| compact=False, sort_dicts=True, \ | ||
| underscore_numbers=False, block_style=False) |
There was a problem hiding this comment.
Likewise
| compact=False, sort_dicts=True, \ | |
| underscore_numbers=False, block_style=False) | |
| block_style=False, compact=False, \ | |
| sort_dicts=True, underscore_numbers=False) |
| compact=False, sort_dicts=True, underscore_numbers=False, | ||
| block_style=False): |
There was a problem hiding this comment.
| compact=False, sort_dicts=True, underscore_numbers=False, | |
| block_style=False): | |
| block_style=False, compact=False, sort_dicts=True, | |
| underscore_numbers=False): |
| pretty-printed json.dumps() when `indent` is supplied. Incompatible | ||
| with compact mode. |
There was a problem hiding this comment.
| pretty-printed json.dumps() when `indent` is supplied. Incompatible | |
| with compact mode. | |
| pretty-printed json.dumps() when ``indent`` is supplied. | |
| Incompatible with compact mode. |
| else: | ||
| return start_str |
There was a problem hiding this comment.
| else: | |
| return start_str | |
| return start_str |
| else: | ||
| return end_str |
There was a problem hiding this comment.
| else: | |
| return end_str | |
| return end_str |
|
|
||
| cls_name = object.__class__.__name__ | ||
| indent += len(cls_name) + 1 | ||
| indent += len(cls_name) + 1 if not self._block_style else self._indent_per_level |
There was a problem hiding this comment.
Please keep to 79/80 characters (PEP 8)
|
@StefanTodoran I think your PR is useful, maybe you can tell if you'll continue working and if so when you can continue working |
|
@donbarbos Sorry about the radio silence, due to work responsibilities my bandwidth is too limited to devote time to this change right now. I can give access to my fork of the repo if someone wants to pick up where I left off. |
thanks, i will be glad to finish this work. but as far as i know the usual practice is to open a new PR, so i can fork your branch and send a new PR to be able to control the PR discussion |
|
Closing in favour of #136964, thanks all. |

Adds a block print option to
pprint. This option is not compatible with compact. Although the original issue only mentions dictionaries, this implementation implements block style for every datastructure supported bypprint. I've been testing it with the code in this gist, which is just a bunch of random datastructures filled with dummy data.