Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -687,6 +687,7 @@ peps/pep-0807.rst @dstufft
peps/pep-0809.rst @zooba
peps/pep-0810.rst @pablogsal @DinoV @Yhg1s
peps/pep-0811.rst @sethmlarson @gpshead
peps/pep-0813.rst @warsaw
# ...
peps/pep-2026.rst @hugovk
# ...
Expand Down
196 changes: 196 additions & 0 deletions peps/pep-0813.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
PEP: 813
Title: The Pretty Print Protocol
Author: Barry Warsaw <[email protected]>
Discussions-To: Pending
Status: Draft
Type: Standards Track
Created: 07-Nov-2025
Python-Version: 3.15
Post-History: Pending


Abstract
========

This PEP describes the "pretty print protocol", a collection of changes proposed to make pretty printing more
customizable and convenient.
Comment on lines +15 to +16
Copy link
Member

@AA-Turner AA-Turner Nov 8, 2025

Choose a reason for hiding this comment

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

It'd be useful to note that implementation is via the __pretty__ dunder (& the change to print?) here, even if just in a single sentence.



Motivation
==========

"Pretty printing" is a feature which provides a capability to format object representations for better
readability. The core functionality is implemented by the standard library :mod:`pprint`. ``pprint``
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
readability. The core functionality is implemented by the standard library :mod:`pprint`. ``pprint``
readability. The core functionality is implemented by the standard library :mod:`pprint` module. ``pprint``

includes a class and APIs which users can invoke to format and print more readable representations of objects.
Copy link
Member

Choose a reason for hiding this comment

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

This is implicitly versus repr(), perhaps useful to say so explicitly?

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

Choose a reason for hiding this comment

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

I'd say a key use case is interactive debugging, pretty-printing by default is a big reason I use IPython.


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

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.



Rationale
=========

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.
Comment on lines +34 to +36
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.


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.
Comment on lines +38 to +40
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.


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.



Specification
=============

There are two parts to this proposal.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
There are two parts to this proposal.
There are two parts to this proposal;
a new dunder method and a change to :func:`print`.



``__pretty__()`` methods
------------------------

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
Comment on lines +55 to +56
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure I follow here, pprint uses custom logic to generate 'pretty' reprs rather than delegating to e.g. container object __repr__() methods. I.e. I'd leave out 'pretty' on the second line here, but I don't know if this matches your thinking.

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
method used to generate a pretty representation of the object. Since object reprs provide functionality
method used to generate a custom 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.


``__pretty__()`` is optional; if missing, the standard pretty printers fall back to ``__repr__()``
for full backward compatibility (technically speaking, :py:func:`python:pprint.saferepr` is used).
Copy link
Member

Choose a reason for hiding this comment

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

Is always using saferepr part of the PEP spec here?

However, if defined on a class, ``__pretty__()`` has the same argument signature as
:py:meth:`python:pprint.PrettyPrinter.format`, taking four arguments:
Copy link
Member

Choose a reason for hiding this comment

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

Is this four in addition to self? (i.e. def __pretty__(self, object, context, maxlevels, levels): ...)


* ``object`` - the object to print, which is effectively always ``self``
* ``context`` - a dictionary mapping the ``id()`` of objects which are part of the current presentation
context
* ``maxlevels`` - the requested limit to recursion
Copy link
Member

Choose a reason for hiding this comment

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

naming: suggest using an underscore?

Suggested change
* ``maxlevels`` - the requested limit to recursion
* ``maxlevels`` - the requested limit to recursion (integer)

* ``levels`` - the current recursion level
Copy link
Member

Choose a reason for hiding this comment

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

If this is the current level, should it be singular instead of plural?

Suggested change
* ``levels`` - the current recursion level
* ``levels`` - the current recursion level (integer)


Similarly, ``__pretty__()`` returns three values, the string to be used as the pretty printed representation,
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
Similarly, ``__pretty__()`` returns three values, the string to be used as the pretty printed representation,
Similarly, ``__pretty__()`` returns three values: the string to be used as the pretty printed representation,

a boolean indicating whether the returned value is "readable", and a boolean indicating whether recursion has
been detected. In this context, "readable" means the same as
:py:meth:`python:pprint.PrettyPrinter.isreadable`, i.e. that the returned value can be used to reconstruct the
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
:py:meth:`python:pprint.PrettyPrinter.isreadable`, i.e. that the returned value can be used to reconstruct the
:py:meth:`~pprint.PrettyPrinter.isreadable`, i.e. that the returned value can be used to reconstruct the

original object using ``eval()``.

See :py:meth:`python:pprint.PrettyPrinter.format` for details.


A new argument to built-in ``print``
------------------------------------

Built-in :func:`print` takes a new optional argument, appended to the end of the argument list, called
``pretty``, which can take one of the following values:

* ``None`` - the default. No pretty printing is invoked. Fully backward compatible.
* ``True`` - use a temporary instance of the :py:class:`python:pprint.PrettyPrinter` class to get a
pretty representation of the object.
* An instance with a ``pformat()`` method, which has the same signature as
:py:meth:`python:pprint.PrettyPrinter.pformat`. When given, this will usually be an instance of a
subclass of ``PrettyPrinter`` with its ``pformat()`` method overridden. Note that this form
requires **an instance** of a pretty printer, not a class, as only ``print(..., pretty=True)``
performs implicit instantiation.


Examples
========

A custom ``__pprint__()`` method can be used to customize the representation of the object:
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
A custom ``__pprint__()`` method can be used to customize the representation of the object:
A custom ``__pretty__()`` method can be used to customize the representation of the object:


.. code-block::
>>> class Custom:
... def __str__(self): return 'my str'
... def __repr__(self): return 'my repr'
... def __pprint__(self, context, maxlevels, level):
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
... def __pprint__(self, context, maxlevels, level):
... def __pretty__(self, context, maxlevels, level):

... return 'my pprint', False, False
>>> pprint.pp(Custom())
my pprint
Comment on lines +108 to +109
Copy link
Member

Choose a reason for hiding this comment

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

Is the intent for PrettyPrinter to change to respect __pretty__ methods? I don't think I saw that above in the spec, but I may have missed it, sorry!

Using the ``pretty`` argument to ``print()``:

.. code-block::
>>> import os
>>> print(os.pathconf_names)
{'PC_ASYNC_IO': 17, 'PC_CHOWN_RESTRICTED': 7, 'PC_FILESIZEBITS': 18, 'PC_LINK_MAX': 1, 'PC_MAX_CANON': 2, 'PC_MAX_INPUT': 3, 'PC_NAME_MAX': 4, 'PC_NO_TRUNC': 8, 'PC_PATH_MAX': 5, 'PC_PIPE_BUF': 6, 'PC_PRIO_IO': 19, 'PC_SYNC_IO': 25, 'PC_VDISABLE': 9, 'PC_MIN_HOLE_SIZE': 27, 'PC_ALLOC_SIZE_MIN': 16, 'PC_REC_INCR_XFER_SIZE': 20, 'PC_REC_MAX_XFER_SIZE': 21, 'PC_REC_MIN_XFER_SIZE': 22, 'PC_REC_XFER_ALIGN': 23, 'PC_SYMLINK_MAX': 24}
>>> print(os.pathconf_names, pretty=True)
{'PC_ALLOC_SIZE_MIN': 16,
'PC_ASYNC_IO': 17,
'PC_CHOWN_RESTRICTED': 7,
'PC_FILESIZEBITS': 18,
'PC_LINK_MAX': 1,
'PC_MAX_CANON': 2,
'PC_MAX_INPUT': 3,
'PC_MIN_HOLE_SIZE': 27,
'PC_NAME_MAX': 4,
'PC_NO_TRUNC': 8,
'PC_PATH_MAX': 5,
'PC_PIPE_BUF': 6,
'PC_PRIO_IO': 19,
'PC_REC_INCR_XFER_SIZE': 20,
'PC_REC_MAX_XFER_SIZE': 21,
'PC_REC_MIN_XFER_SIZE': 22,
'PC_REC_XFER_ALIGN': 23,
'PC_SYMLINK_MAX': 24,
'PC_SYNC_IO': 25,
'PC_VDISABLE': 9}
Backwards Compatibility
=======================

When none of the new features are used, this PEP is fully backward compatible, both for built-in
``print()`` and the ``pprint`` module.


Security Implications
=====================

There are no known security implications for this proposal.


How to Teach This
=================

Documentation and examples are added to the ``pprint`` module and the ``print()`` function.
Beginners don't need to be taught these new features until they want prettier representations of
their objects.


Reference Implementation
========================

The reference implementation is currently available as a `PEP author branch of the CPython main
branch <https://github.com/warsaw/cpython/tree/pprint>`__.


Rejected Ideas
==============

None at this time.


Open Issues
===========

TBD

Acknowledgements
================

TBD


Footnotes
=========

TBD


Copyright
=========

This document is placed in the public domain or under the
CC0-1.0-Universal license, whichever is more permissive.