Skip to content

Conversation

@warsaw
Copy link
Member

@warsaw warsaw commented Nov 7, 2025

Basic requirements (all PEP Types)

  • Read and followed PEP 1 & PEP 12
  • File created from the latest PEP template
  • PEP has next available number, & set in filename (pep-NNNN.rst), PR title (PEP 123: <Title of PEP>) and PEP header
  • Title clearly, accurately and concisely describes the content in 79 characters or less
  • Core dev/PEP editor listed as Author or Sponsor, and formally confirmed their approval
  • Author, Status (Draft), Type and Created headers filled out correctly
  • PEP-Delegate, Topic, Requires and Replaces headers completed if appropriate
  • Required sections included
    • Abstract (first section)
    • Copyright (last section; exact wording from template required)
  • Code is well-formatted (PEP 7/PEP 8) and is in code blocks, with the right lexer names if non-Python
  • PEP builds with no warnings, pre-commit checks pass and content displays as intended in the rendered HTML
  • Authors/sponsor added to .github/CODEOWNERS for the PEP

Standards Track requirements

  • PEP topic discussed in a suitable venue with general agreement that a PEP is appropriate
  • Suggested sections included (unless not applicable)
    • Motivation
    • Rationale
    • Specification
    • Backwards Compatibility
    • Security Implications
    • How to Teach This
    • Reference Implementation
    • Rejected Ideas
    • Open Issues
  • Python-Version set to valid (pre-beta) future Python version, if relevant
  • Any project stated in the PEP as supporting/endorsing/benefiting from the PEP formally confirmed such
  • Right before or after initial merging, PEP discussion thread created and linked to in Discussions-To and Post-History

📚 Documentation preview 📚: https://pep-previews--4690.org.readthedocs.build/pep-0813/

@warsaw warsaw requested a review from a team as a code owner November 7, 2025 17:21
warsaw added a commit to warsaw/cpython that referenced this pull request Nov 7, 2025
Copy link
Member

@hugovk hugovk left a comment

Choose a reason for hiding this comment

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

Looks useful!

@hugovk hugovk added the new-pep A new draft PEP submitted for initial review label Nov 7, 2025
warsaw and others added 2 commits November 7, 2025 12:28
Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
@warsaw warsaw self-assigned this Nov 7, 2025
Copy link
Member

@AA-Turner AA-Turner left a comment

Choose a reason for hiding this comment

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

Sorry for the slight delay in initial review!

Mostly editorial comments in line, a couple of questions where I didn't follow the text too.

A slightly more substantive point I think it'd be useful to address is what style/form of prettiness will be chosen -- I'm thinking here of the proposed(?) change to pprint to add block-style formatting, similar to how code is often formatted in source form, rather than the more traditional pprint approach (as illustrated in the examples here). Personally, I'd always want to use the block-style if possible, but my understanding of the current proposal is that options like that wouldn't be possible.

A

Copy link
Contributor

@willingc willingc left a comment

Choose a reason for hiding this comment

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

Nice. A few clarifications in addition to Adam's.

includes a class and APIs which users can invoke to format and print more readable representations of objects.
Important use cases include pretty printing large dictionaries and other complicated objects.

The ``pprint`` module is great as far as it goes. This PEP builds on the features of this module to provide
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
The ``pprint`` module is great as far as it goes. This PEP builds on the features of this module to provide
The ``pprint`` module provides fundamentals for user-readable information display. This PEP builds on the features of this module to provide

Important use cases include pretty printing large dictionaries and other complicated objects.

The ``pprint`` module is great as far as it goes. This PEP builds on the features of this module to provide
more customization and convenience.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
more customization and convenience.
more customization, display structure, and user convenience.

Comment on lines +34 to +36
Pretty printing is very useful for displaying complex data structures, like dictionaries read from JSON
content. By providing a way for classes to customize how their instances participate in pretty printing,
users have more options for visually improving the display and debugging of their complex data.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
Pretty printing is very useful for displaying complex data structures, like dictionaries read from JSON
content. By providing a way for classes to customize how their instances participate in pretty printing,
users have more options for visually improving the display and debugging of their complex data.
Pretty printing is very useful for displaying complex data structures, like dictionaries read from JSON
content. Through class customization options for pretty printing,
users have more options for visually improving the display and debugging of their complex data.

Comment on lines +38 to +40
By extending the built-in :func:`print` function to automatically pretty print its output, this feature is
made even more convenient, since no extra imports are required, and users can easily just piggyback on
well-worn "print debugging" patterns, at least for the most common use cases.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
By extending the built-in :func:`print` function to automatically pretty print its output, this feature is
made even more convenient, since no extra imports are required, and users can easily just piggyback on
well-worn "print debugging" patterns, at least for the most common use cases.
By extending the built-in :func:`print` function to automatically pretty print its output, user-readable display is
made even more convenient. Since no extra imports are required, users can easily piggyback on
well-worn "print debugging" patterns for most common use cases.

made even more convenient, since no extra imports are required, and users can easily just piggyback on
well-worn "print debugging" patterns, at least for the most common use cases.

These two extensions work independently, but hand-in-hand can provide a powerful and convenient new feature.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
These two extensions work independently, but hand-in-hand can provide a powerful and convenient new feature.
These two extensions, class customization for pretty printing and default print behavior, work independently but can be used in conjunction to provide a powerful and convenient user display of information.

Classes can implement a new dunder method, ``__pretty__()`` which if present, generates the pretty printed
representation of their instances. This augments ``__repr__()`` which, prior to this proposal, was the only
method used to generate a pretty representation of the object. Since object reprs provide functionality
distinct from pretty printing, some classes may want more control over their pretty display.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
distinct from pretty printing, some classes may want more control over their pretty display.
structured representation distinct from pretty printing, some classes may benefit from more control over pretty visual display of their instances.

@warsaw
Copy link
Member Author

warsaw commented Nov 12, 2025

Sorry for the slight delay in initial review!

No worries! I was on vacation so I'm just getting back to this now.

Mostly editorial comments in line, a couple of questions where I didn't follow the text too.

Very much appreciated!

A slightly more substantive point I think it'd be useful to address is what style/form of prettiness will be chosen -- I'm thinking here of the proposed(?) change to pprint to add block-style formatting, similar to how code is often formatted in source form, rather than the more traditional pprint approach (as illustrated in the examples here). Personally, I'd always want to use the block-style if possible, but my understanding of the current proposal is that options like that wouldn't be possible.

While I prefer to defer substantive discussions to the inevitable mega-DPO thread, I think a possible way to handle this would be to use a different PrettyPrinter.pformat() method. Given that print(..., pretty=True) just instantiates pprint.PrettyPrinter and then calls its pformat() function, we could use a new or different default which had something like the block-style formatting you propose.

I'll have to discuss with @ericvsmith as we move forward with the proposal.

warsaw and others added 5 commits November 12, 2025 15:18
Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com>
Co-authored-by: Carol Willing <carolcode@willingconsulting.com>
@willmcgugan
Copy link

Hi foks,

Can I be bold (and possibly also italic and underline) and suggest that this should become something like Rich's rich repr protocol. If not adopt it entirely.

In its current form, it looks like most of the work in formatting something as "pretty" is left to the object implementing __pprint__. This may give the most freedom but it would require effort from the author of the object. Pretty output often requires extensive string processing, and has a potentially large footprint for errors.

Because Rich's __rich_repr__ is declarative it moves the work of generating the pretty output to the library, where there is less chance of breaking anything. It also allows the library to make the decision how and when to break the object output on to multiple lines.

The rich repr approach does place some limitations on the output. The author couldn't generate absolutely anything in pretty output, but I consider this to be a plus. The pretty output will always look like formatted code in your editor, as you couldn't generate anything too crazy with this approach. Other features like color and indent guides are optional, but would remain possible.

Example Rich output for context:

Screenshot 2025-11-15 at 18 18 16

Will (Rich guy)

@warsaw
Copy link
Member Author

warsaw commented Nov 17, 2025

If not adopt it entirely.

That's really interesting and powerful @willmcgugan, thanks for the reference. @ericvsmith and I have been thinking about how to improve the proposal to make things more flexible, and this is a really good real-world example of what it might look like.

Have you had any problems or suggestions for improving rich's pretty printing?

I wonder about adopting it directly. I'm not sure how well that will play with the stdlib pprint module, or how complicated rich's pretty printer implementation is (something I will TAL at when I get some time).

Even if it isn't feasible to adopt directly, I'd want to think about ways to make them interoperate seamlessly.

@willmcgugan
Copy link

The implementation is a little gnarly.

Much of the complexity came from introspection. __repr__ methods that crashed, which is common in objects from ORMs, where it was assumed the database layer would exist. Also objects with __getattr__ implemented that claim they support all attributes. Haven't had any for a while, but there will be plenty of such edge cases in the Rich issues.

I'd also like to echo @AA-Turner 's comments about the formatting. I don't consider pprint's output to be pretty any more. It was pre-Python3 and pre-black. I think most people will have an expectation that "pretty" is how your editor would auto-format a data-structure.

Feel free to mention me any time. I'm interested in following along on this one.

@warsaw
Copy link
Member Author

warsaw commented Nov 24, 2025

@willmcgugan - Being off for the USA Thanksgiving holiday, it's given me a chance to dive into this in more detail.

I'd also like to echo @AA-Turner 's comments about the formatting. I don't consider pprint's output to be pretty any more. It was pre-Python3 and pre-black. I think most people will have an expectation that "pretty" is how your editor would auto-format a data-structure.

I don't disagree, but I want "fixing pprint" to be out of scope for this PEP. What occurs to me is that with something @ericvsmith mentioned in DM and looking at the __rich_repr__ protocol, I think we can design something that uses built-in pprint if that's all you've got and lets you plug in Rich's pretty printer if you want to take on that dependency. Let me sketch it out.

@ericvsmith mentioned __pprint__ "returning a list of strings" so that the machinery would essentially have the parts to format however it wants. The rich.repr.Result type expands to typing.Iterable[typing.Any | typing.Tuple[typing.Any] | typing.Tuple[str, typing.Any] | typing.Tuple[str, typing.Any, typing.Any]]. PEP 813 currently says that __pprint__() always returns a 3-tuple, identical to pprint.PrettyPrinter.format(). Can we fit these together somehow?

Questions:

  • Rich doesn't have any notion of a pretty repr being "readable" which really means that there's an expectation that the pretty printed repr can reconstruct the instance using eval(). Looking at the examples in the Rich docs, it seems like it could support this (see the pretty repr of the Bird instance without angular=True, but there's no way for __rich_repr__ to communicate whether that's true or not. If we were to change PEP 813 to return lists of strings even without merging the ideas, that would also be difficult for __pprint__() to communicate, because there's no one return value that says "here are the characteristics of the entire pretty representation". Do we care? Would it make any sense for e.g. the first thing returned from the iterable would be a "property dict" or some such?
  • __rich_repr__ doesn't support the recursion boolean flag. How does rich.print handle recursion?
  • Similarly, __pprint__() in PEP 813 takes 4 arguments (well, self + 3), with context, maxlevels, and levels being useful for recursion detection. However, that puts the onus on the author of __pprint__() to detect recursion, and that's not ideal. I'd much prefer the machinery handle possible recursion and have __pprint__() (a.k.a. __rich_repr__()) take a single argument: the object being pretty printed, i.e. self.
  • If we can merge the ideas, it seems like it would be pretty (pun intended) trivial to converge on the method name. I think @ericvsmith and I still like __pprint__() and wouldn't want to leak the "rich" name in it like __rich_repr__ but that seems like it'd be an easy and backward compatible enhancement to Rich, both in defining a __pprint__() method in @rich.repr.auto and in the consumption of the results in rich.print().
  • With the proposed change to built-in print(..., pretty=someobj), does Rich have something that could provide that API, like a duck-class of pprint.PrettyPrinter with a method like pformat()? I could kind of imagine that thing taking arguments like rich.print() such as expand_all, max_length, max_string, and maybe even angular. That'd be the glue between print(..., pretty=someobj) and Rich's pretty printer.

@ericvsmith 's also been playing around with a new !p converter to f-strings, so maybe he has ideas about how that would fit in as well.

TL;DR: it doesn't seem like we're all that far off!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

new-pep A new draft PEP submitted for initial review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants