Skip to content

Commit fe61924

Browse files
committed
The pre-PEP
1 parent 9ed491a commit fe61924

File tree

1 file changed

+154
-0
lines changed

1 file changed

+154
-0
lines changed

pep-9999.rst

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
PEP: 9999
2+
Title: The pprint protocol
3+
Author: Barry Warsaw <[email protected]>,
4+
Eric V. Smith <eric at trueblade.com>
5+
Discussions-To: Pending
6+
Status: Draft
7+
Type: Standards Track
8+
Created: 03-Nov-2025
9+
Python-Version: 3.15
10+
Post-History: Pending
11+
12+
13+
Abstract
14+
========
15+
16+
This PEP describes the "pprint protocol", a collection of changes proposed to make pretty printing more
17+
customizable and convenient.
18+
19+
20+
Motivation
21+
==========
22+
23+
"Pretty printing" is a feature which provides a capability to format object representations for better
24+
readability. The core functionality is implemented by the standard library :mod:`pprint`. ``pprint``
25+
includes a class and APIs which users can invoke to format and print more readable representations of objects.
26+
Important use cases include pretty printing large dictionaries and other complicated objects.
27+
28+
The ``pprint`` module is great as far as it goes. This PEP builds on the features of this module to provide
29+
more customization and convenience.
30+
31+
32+
Rationale
33+
=========
34+
35+
Pretty printing is very useful for displaying complex data structures, like dictionaries read from JSON
36+
content. By providing a way for classes to customize how their instances participate in pretty printing,
37+
users have more options for visually improving the display and debugging of their complex data.
38+
39+
By extending the built-in :py:func:`print` function to automatically pretty print its output, this feature is
40+
made even more convenient, since no extra imports are required, and users can easily just piggyback on
41+
well-worn "print debugging" patterns, at least for the most common use cases.
42+
43+
These two extensions work independently, but hand-in-hand can provide a powerful and convenient new feature.
44+
45+
46+
Specification
47+
=============
48+
49+
There are two parts to this proposal.
50+
51+
52+
``__pretty__()`` methods
53+
------------------------
54+
55+
Classes can implement a new dunder method, ``__pretty__()`` which if present, generates the pretty printed
56+
representation of their instances. This augments ``__repr__()`` which, prior to this proposal, was the only
57+
method used to generate a pretty representation of the object. Since the built-in :py:func:`repr` function
58+
provides functionality potentially separate from pretty printing, some classes may want more control over
59+
object display between those two use cases.
60+
61+
``__pretty__()`` is optional; if missing, the standard pretty printers fall back to ``__repr__()`` for full
62+
backward compatibility. However, if defined on a class, ``__pretty__()`` has the same argument signature as
63+
:py:func:`PrettyPrinter.format`, taking four arguments:
64+
65+
* ``object`` - the object to print, which is effectively always ``self``
66+
* ``context`` - a dictionary mapping the ``id()`` of objects which are part of the current presentation
67+
context
68+
* ``maxlevels`` - the requested limit to recursion
69+
* ``levels`` - the current recursion level
70+
71+
See :py:func:`PrettyPrinter.format` for details.
72+
73+
Unlike that function, ``__pretty__()`` returns a single value, the string to be used as the pretty printed
74+
representation.
75+
76+
77+
A new argument to built-in ``print``
78+
------------------------------------
79+
80+
Built-in :py:func:`print` takes a new optional argument, appended to the end of the argument list, called
81+
``pretty``, which can take one of the following values:
82+
83+
* ``None`` - the default; fully backward compatible
84+
* ``True`` - use a temporary instance of the :py:class:`PrettyPrinter` class to get a pretty representation of
85+
the object.
86+
* An instance with a ``pformat()`` method, which has the same signature as
87+
:meth:`PrettyPrinter.pformat`. When given, this will usually be an instance of a subclass of
88+
`PrettyPrinter` with its `pformat()` method overridden. Note that this form requires **an
89+
instance** of a pretty printer, not a class, as only ``print(..., pretty=True)`` performs implicit
90+
instantiation.
91+
92+
93+
Backwards Compatibility
94+
=======================
95+
96+
When none of the new features are used, this PEP is fully backward compatible, both for built-in
97+
``print()`` and the ``pprint`` module.
98+
99+
100+
Security Implications
101+
=====================
102+
103+
There are no known security implications for this proposal.
104+
105+
106+
How to Teach This
107+
=================
108+
109+
Documentation and examples are added to the ``pprint`` module and the ``print()`` function.
110+
Beginners don't need to be taught these new features until they want prettier representations of
111+
their objects.
112+
113+
114+
Reference Implementation
115+
========================
116+
117+
The reference implementation is currently available as a `PEP author branch of the CPython main
118+
branch <https://github.com/warsaw/cpython/tree/pprint>`__.
119+
120+
121+
Rejected Ideas
122+
==============
123+
124+
None at this time.
125+
126+
127+
Open Issues
128+
===========
129+
130+
As currently defined, the ``__pretty__()`` method is defined as taking four arguments and returning
131+
a single string. This is close to -- but not quite -- the full signature for
132+
``PrettyPrinter.format()``, and was chosen for reference implementation convenience. It's not
133+
clear that custom pretty representations need ``context``, ``maxlevels``, and ``levels``, so perhaps
134+
the argument list should be simplified? If not, then perhaps ``__pretty__()`` should *exactly*
135+
match ``PrettyPrinter.format()``? That does, however complicate the protocol for users.
136+
137+
138+
Acknowledgements
139+
================
140+
141+
TBD
142+
143+
144+
Footnotes
145+
=========
146+
147+
TBD
148+
149+
150+
Copyright
151+
=========
152+
153+
This document is placed in the public domain or under the
154+
CC0-1.0-Universal license, whichever is more permissive.

0 commit comments

Comments
 (0)