Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
398f467
PEP 813: The Pretty Print Protocol
warsaw Nov 7, 2025
25c70f7
The Elder Statesmen of Python
warsaw Nov 7, 2025
5555617
Fix markup errors
warsaw Nov 7, 2025
cd0a257
One more linting bug
warsaw Nov 7, 2025
1d4b9d1
Exmaple fixes
warsaw Nov 7, 2025
b8fc7e4
Alone again, naturally
warsaw Nov 7, 2025
263a95b
Update peps/pep-0813.rst
warsaw Nov 7, 2025
143cb6c
The dunder is __pprint__(), not __pretty__()
warsaw Nov 7, 2025
a8598f7
Update peps/pep-0813.rst
warsaw Nov 12, 2025
1a96c8d
Merge branch 'pep-813-pprint' of github.com:warsaw/peps into pep-813-…
warsaw Nov 12, 2025
2703f5c
Update based on @AA-Turner's feedback
warsaw Nov 12, 2025
686fc4d
Update peps/pep-0813.rst
warsaw Nov 12, 2025
94d20f5
Merge branch 'main' into pep-813-pprint
warsaw Nov 12, 2025
1cf369c
Merge branch 'main' into pep-813-pprint
warsaw Nov 17, 2025
062eef6
Update CODEOWNERS
warsaw Nov 17, 2025
8f744fb
Merge branch 'main' into pep-813-pprint
warsaw Nov 17, 2025
c8212a9
Merge branch 'main' into pep-813-pprint
warsaw Nov 29, 2025
93b0d6e
Merge branch 'main' into pep-813-pprint
warsaw Dec 22, 2025
dfd5667
Update the PEP to match the latest decisions, and reference implement…
warsaw Dec 23, 2025
a876bed
Merge branch 'main' into pep-813-pprint
warsaw Jan 7, 2026
be4fd43
Merge branch 'main' into pep-813-pprint
warsaw Feb 17, 2026
a835595
Update peps/pep-0813.rst
warsaw Feb 17, 2026
97d9d1a
Update peps/pep-0813.rst
warsaw Feb 17, 2026
bba5028
Update peps/pep-0813.rst
warsaw Feb 17, 2026
9c088d3
Mention restriction of the existing pprint module. Add a section on !…
ericvsmith Feb 21, 2026
1329a0c
Merge pull request #2 from ericvsmith/pep-813-pprint
warsaw Feb 21, 2026
e08af1c
Fix Sphinx syntax
warsaw Feb 21, 2026
326d8de
Merge branch 'main' into pep-813-pprint
warsaw Feb 21, 2026
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 <barry@python.org>
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 thread
warsaw marked this conversation as resolved.


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``
Comment thread
warsaw marked this conversation as resolved.
Outdated
includes a class and APIs which users can invoke to format and print more readable representations of objects.
Comment thread
warsaw marked this conversation as resolved.
Outdated
Important use cases include pretty printing large dictionaries and other complicated objects.
Comment thread
warsaw marked this conversation as resolved.
Outdated

The ``pprint`` module is great as far as it goes. This PEP builds on the features of this module to provide
Comment thread
warsaw marked this conversation as resolved.
Outdated
more customization and convenience.
Comment thread
warsaw marked this conversation as resolved.
Outdated


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 thread
warsaw marked this conversation as resolved.
Outdated

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 thread
warsaw marked this conversation as resolved.
Outdated

These two extensions work independently, but hand-in-hand can provide a powerful and convenient new feature.
Comment thread
warsaw marked this conversation as resolved.
Outdated


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

There are two parts to this proposal.
Comment thread
warsaw marked this conversation as resolved.
Outdated


``__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 thread
warsaw marked this conversation as resolved.
Outdated
Comment thread
warsaw marked this conversation as resolved.
Outdated
distinct from pretty printing, some classes may want more control over their pretty display.
Comment thread
warsaw marked this conversation as resolved.
Outdated

``__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).
Comment thread
warsaw marked this conversation as resolved.
Outdated
However, if defined on a class, ``__pretty__()`` has the same argument signature as
:py:meth:`python:pprint.PrettyPrinter.format`, taking four arguments:
Comment thread
warsaw marked this conversation as resolved.
Outdated

* ``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
Comment thread
warsaw marked this conversation as resolved.
Outdated
* ``levels`` - the current recursion level
Comment thread
warsaw marked this conversation as resolved.
Outdated

Similarly, ``__pretty__()`` returns three values, the string to be used as the pretty printed representation,
Comment thread
warsaw marked this conversation as resolved.
Outdated
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
Comment thread
warsaw marked this conversation as resolved.
Outdated
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:
Comment thread
warsaw marked this conversation as resolved.
Outdated

.. code-block::

>>> class Custom:
... def __str__(self): return 'my str'
... def __repr__(self): return 'my repr'
... def __pprint__(self, context, maxlevels, level):
Comment thread
warsaw marked this conversation as resolved.
Outdated
... return 'my pprint', False, False

>>> pprint.pp(Custom())
my pprint
Comment thread
warsaw marked this conversation as resolved.
Outdated

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.
Comment thread
warsaw marked this conversation as resolved.