Skip to content
Open
Show file tree
Hide file tree
Changes from 7 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.


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``
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

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 +35 to +37
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 +39 to +41
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.


``__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
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.

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:

* ``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,
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:

.. code-block::
>>> class Custom:
... def __str__(self): return 'my str'
... def __repr__(self): return 'my repr'
... def __pprint__(self, context, maxlevels, level):
... return 'my pprint', False, False
>>> pprint.pp(Custom())
my pprint
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.