1:mod:`pprint` --- Data pretty printer
2=====================================
3
4.. module:: pprint
5   :synopsis: Data pretty printer.
6
7.. moduleauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
8.. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
9
10**Source code:** :source:`Lib/pprint.py`
11
12--------------
13
14The :mod:`pprint` module provides a capability to "pretty-print" arbitrary
15Python data structures in a form which can be used as input to the interpreter.
16If the formatted structures include objects which are not fundamental Python
17types, the representation may not be loadable.  This may be the case if objects
18such as files, sockets or classes are included, as well as many other
19objects which are not representable as Python literals.
20
21The formatted representation keeps objects on a single line if it can, and
22breaks them onto multiple lines if they don't fit within the allowed width.
23Construct :class:`PrettyPrinter` objects explicitly if you need to adjust the
24width constraint.
25
26Dictionaries are sorted by key before the display is computed.
27
28The :mod:`pprint` module defines one class:
29
30.. First the implementation class:
31
32
33.. index:: single: ...; placeholder
34
35.. class:: PrettyPrinter(indent=1, width=80, depth=None, stream=None, *, \
36                         compact=False, sort_dicts=True)
37
38   Construct a :class:`PrettyPrinter` instance.  This constructor understands
39   several keyword parameters.  An output stream may be set using the *stream*
40   keyword; the only method used on the stream object is the file protocol's
41   :meth:`write` method.  If not specified, the :class:`PrettyPrinter` adopts
42   ``sys.stdout``.  The
43   amount of indentation added for each recursive level is specified by *indent*;
44   the default is one.  Other values can cause output to look a little odd, but can
45   make nesting easier to spot.  The number of levels which may be printed is
46   controlled by *depth*; if the data structure being printed is too deep, the next
47   contained level is replaced by ``...``.  By default, there is no constraint on
48   the depth of the objects being formatted.  The desired output width is
49   constrained using the *width* parameter; the default is 80 characters.  If a
50   structure cannot be formatted within the constrained width, a best effort will
51   be made.  If *compact* is false (the default) each item of a long sequence
52   will be formatted on a separate line.  If *compact* is true, as many items
53   as will fit within the *width* will be formatted on each output line. If
54   *sort_dicts* is true (the default), dictionaries will be formatted with their
55   keys sorted, otherwise they will display in insertion order.
56
57   .. versionchanged:: 3.4
58      Added the *compact* parameter.
59
60   .. versionchanged:: 3.8
61      Added the *sort_dicts* parameter.
62
63
64      >>> import pprint
65      >>> stuff = ['spam', 'eggs', 'lumberjack', 'knights', 'ni']
66      >>> stuff.insert(0, stuff[:])
67      >>> pp = pprint.PrettyPrinter(indent=4)
68      >>> pp.pprint(stuff)
69      [   ['spam', 'eggs', 'lumberjack', 'knights', 'ni'],
70          'spam',
71          'eggs',
72          'lumberjack',
73          'knights',
74          'ni']
75      >>> pp = pprint.PrettyPrinter(width=41, compact=True)
76      >>> pp.pprint(stuff)
77      [['spam', 'eggs', 'lumberjack',
78        'knights', 'ni'],
79       'spam', 'eggs', 'lumberjack', 'knights',
80       'ni']
81      >>> tup = ('spam', ('eggs', ('lumberjack', ('knights', ('ni', ('dead',
82      ... ('parrot', ('fresh fruit',))))))))
83      >>> pp = pprint.PrettyPrinter(depth=6)
84      >>> pp.pprint(tup)
85      ('spam', ('eggs', ('lumberjack', ('knights', ('ni', ('dead', (...)))))))
86
87
88The :mod:`pprint` module also provides several shortcut functions:
89
90.. function:: pformat(object, indent=1, width=80, depth=None, *, \
91                      compact=False, sort_dicts=True)
92
93   Return the formatted representation of *object* as a string.  *indent*,
94   *width*, *depth*, *compact* and *sort_dicts* will be passed to the
95   :class:`PrettyPrinter` constructor as formatting parameters.
96
97   .. versionchanged:: 3.4
98      Added the *compact* parameter.
99
100   .. versionchanged:: 3.8
101      Added the *sort_dicts* parameter.
102
103
104.. function:: pp(object, *args, sort_dicts=False, **kwargs)
105
106   Prints the formatted representation of *object* followed by a newline.
107   If *sort_dicts* is false (the default), dictionaries will be displayed with
108   their keys in insertion order, otherwise the dict keys will be sorted.
109   *args* and *kwargs* will be passed to :func:`pprint` as formatting
110   parameters.
111
112   .. versionadded:: 3.8
113
114
115.. function:: pprint(object, stream=None, indent=1, width=80, depth=None, *, \
116                     compact=False, sort_dicts=True)
117
118   Prints the formatted representation of *object* on *stream*, followed by a
119   newline.  If *stream* is ``None``, ``sys.stdout`` is used.  This may be used
120   in the interactive interpreter instead of the :func:`print` function for
121   inspecting values (you can even reassign ``print = pprint.pprint`` for use
122   within a scope).  *indent*, *width*, *depth*, *compact* and *sort_dicts* will
123   be passed to the :class:`PrettyPrinter` constructor as formatting parameters.
124
125   .. versionchanged:: 3.4
126      Added the *compact* parameter.
127
128   .. versionchanged:: 3.8
129      Added the *sort_dicts* parameter.
130
131      >>> import pprint
132      >>> stuff = ['spam', 'eggs', 'lumberjack', 'knights', 'ni']
133      >>> stuff.insert(0, stuff)
134      >>> pprint.pprint(stuff)
135      [<Recursion on list with id=...>,
136       'spam',
137       'eggs',
138       'lumberjack',
139       'knights',
140       'ni']
141
142
143.. function:: isreadable(object)
144
145   .. index:: builtin: eval
146
147   Determine if the formatted representation of *object* is "readable", or can be
148   used to reconstruct the value using :func:`eval`.  This always returns ``False``
149   for recursive objects.
150
151      >>> pprint.isreadable(stuff)
152      False
153
154
155.. function:: isrecursive(object)
156
157   Determine if *object* requires a recursive representation.
158
159
160One more support function is also defined:
161
162.. function:: saferepr(object)
163
164   Return a string representation of *object*, protected against recursive data
165   structures.  If the representation of *object* exposes a recursive entry, the
166   recursive reference will be represented as ``<Recursion on typename with
167   id=number>``.  The representation is not otherwise formatted.
168
169   >>> pprint.saferepr(stuff)
170   "[<Recursion on list with id=...>, 'spam', 'eggs', 'lumberjack', 'knights', 'ni']"
171
172
173.. _prettyprinter-objects:
174
175PrettyPrinter Objects
176---------------------
177
178:class:`PrettyPrinter` instances have the following methods:
179
180
181.. method:: PrettyPrinter.pformat(object)
182
183   Return the formatted representation of *object*.  This takes into account the
184   options passed to the :class:`PrettyPrinter` constructor.
185
186
187.. method:: PrettyPrinter.pprint(object)
188
189   Print the formatted representation of *object* on the configured stream,
190   followed by a newline.
191
192The following methods provide the implementations for the corresponding
193functions of the same names.  Using these methods on an instance is slightly
194more efficient since new :class:`PrettyPrinter` objects don't need to be
195created.
196
197
198.. method:: PrettyPrinter.isreadable(object)
199
200   .. index:: builtin: eval
201
202   Determine if the formatted representation of the object is "readable," or can be
203   used to reconstruct the value using :func:`eval`.  Note that this returns
204   ``False`` for recursive objects.  If the *depth* parameter of the
205   :class:`PrettyPrinter` is set and the object is deeper than allowed, this
206   returns ``False``.
207
208
209.. method:: PrettyPrinter.isrecursive(object)
210
211   Determine if the object requires a recursive representation.
212
213This method is provided as a hook to allow subclasses to modify the way objects
214are converted to strings.  The default implementation uses the internals of the
215:func:`saferepr` implementation.
216
217
218.. method:: PrettyPrinter.format(object, context, maxlevels, level)
219
220   Returns three values: the formatted version of *object* as a string, a flag
221   indicating whether the result is readable, and a flag indicating whether
222   recursion was detected.  The first argument is the object to be presented.  The
223   second is a dictionary which contains the :func:`id` of objects that are part of
224   the current presentation context (direct and indirect containers for *object*
225   that are affecting the presentation) as the keys; if an object needs to be
226   presented which is already represented in *context*, the third return value
227   should be ``True``.  Recursive calls to the :meth:`.format` method should add
228   additional entries for containers to this dictionary.  The third argument,
229   *maxlevels*, gives the requested limit to recursion; this will be ``0`` if there
230   is no requested limit.  This argument should be passed unmodified to recursive
231   calls. The fourth argument, *level*, gives the current level; recursive calls
232   should be passed a value less than that of the current call.
233
234
235.. _pprint-example:
236
237Example
238-------
239
240To demonstrate several uses of the :func:`pprint` function and its parameters,
241let's fetch information about a project from `PyPI <https://pypi.org>`_::
242
243   >>> import json
244   >>> import pprint
245   >>> from urllib.request import urlopen
246   >>> with urlopen('https://pypi.org/pypi/sampleproject/json') as resp:
247   ...     project_info = json.load(resp)['info']
248
249In its basic form, :func:`pprint` shows the whole object::
250
251   >>> pprint.pprint(project_info)
252   {'author': 'The Python Packaging Authority',
253    'author_email': 'pypa-dev@googlegroups.com',
254    'bugtrack_url': None,
255    'classifiers': ['Development Status :: 3 - Alpha',
256                    'Intended Audience :: Developers',
257                    'License :: OSI Approved :: MIT License',
258                    'Programming Language :: Python :: 2',
259                    'Programming Language :: Python :: 2.6',
260                    'Programming Language :: Python :: 2.7',
261                    'Programming Language :: Python :: 3',
262                    'Programming Language :: Python :: 3.2',
263                    'Programming Language :: Python :: 3.3',
264                    'Programming Language :: Python :: 3.4',
265                    'Topic :: Software Development :: Build Tools'],
266    'description': 'A sample Python project\n'
267                   '=======================\n'
268                   '\n'
269                   'This is the description file for the project.\n'
270                   '\n'
271                   'The file should use UTF-8 encoding and be written using '
272                   'ReStructured Text. It\n'
273                   'will be used to generate the project webpage on PyPI, and '
274                   'should be written for\n'
275                   'that purpose.\n'
276                   '\n'
277                   'Typical contents for this file would include an overview of '
278                   'the project, basic\n'
279                   'usage examples, etc. Generally, including the project '
280                   'changelog in here is not\n'
281                   'a good idea, although a simple "What\'s New" section for the '
282                   'most recent version\n'
283                   'may be appropriate.',
284    'description_content_type': None,
285    'docs_url': None,
286    'download_url': 'UNKNOWN',
287    'downloads': {'last_day': -1, 'last_month': -1, 'last_week': -1},
288    'home_page': 'https://github.com/pypa/sampleproject',
289    'keywords': 'sample setuptools development',
290    'license': 'MIT',
291    'maintainer': None,
292    'maintainer_email': None,
293    'name': 'sampleproject',
294    'package_url': 'https://pypi.org/project/sampleproject/',
295    'platform': 'UNKNOWN',
296    'project_url': 'https://pypi.org/project/sampleproject/',
297    'project_urls': {'Download': 'UNKNOWN',
298                     'Homepage': 'https://github.com/pypa/sampleproject'},
299    'release_url': 'https://pypi.org/project/sampleproject/1.2.0/',
300    'requires_dist': None,
301    'requires_python': None,
302    'summary': 'A sample Python project',
303    'version': '1.2.0'}
304
305The result can be limited to a certain *depth* (ellipsis is used for deeper
306contents)::
307
308   >>> pprint.pprint(project_info, depth=1)
309   {'author': 'The Python Packaging Authority',
310    'author_email': 'pypa-dev@googlegroups.com',
311    'bugtrack_url': None,
312    'classifiers': [...],
313    'description': 'A sample Python project\n'
314                   '=======================\n'
315                   '\n'
316                   'This is the description file for the project.\n'
317                   '\n'
318                   'The file should use UTF-8 encoding and be written using '
319                   'ReStructured Text. It\n'
320                   'will be used to generate the project webpage on PyPI, and '
321                   'should be written for\n'
322                   'that purpose.\n'
323                   '\n'
324                   'Typical contents for this file would include an overview of '
325                   'the project, basic\n'
326                   'usage examples, etc. Generally, including the project '
327                   'changelog in here is not\n'
328                   'a good idea, although a simple "What\'s New" section for the '
329                   'most recent version\n'
330                   'may be appropriate.',
331    'description_content_type': None,
332    'docs_url': None,
333    'download_url': 'UNKNOWN',
334    'downloads': {...},
335    'home_page': 'https://github.com/pypa/sampleproject',
336    'keywords': 'sample setuptools development',
337    'license': 'MIT',
338    'maintainer': None,
339    'maintainer_email': None,
340    'name': 'sampleproject',
341    'package_url': 'https://pypi.org/project/sampleproject/',
342    'platform': 'UNKNOWN',
343    'project_url': 'https://pypi.org/project/sampleproject/',
344    'project_urls': {...},
345    'release_url': 'https://pypi.org/project/sampleproject/1.2.0/',
346    'requires_dist': None,
347    'requires_python': None,
348    'summary': 'A sample Python project',
349    'version': '1.2.0'}
350
351Additionally, maximum character *width* can be suggested. If a long object
352cannot be split, the specified width will be exceeded::
353
354   >>> pprint.pprint(project_info, depth=1, width=60)
355   {'author': 'The Python Packaging Authority',
356    'author_email': 'pypa-dev@googlegroups.com',
357    'bugtrack_url': None,
358    'classifiers': [...],
359    'description': 'A sample Python project\n'
360                   '=======================\n'
361                   '\n'
362                   'This is the description file for the '
363                   'project.\n'
364                   '\n'
365                   'The file should use UTF-8 encoding and be '
366                   'written using ReStructured Text. It\n'
367                   'will be used to generate the project '
368                   'webpage on PyPI, and should be written '
369                   'for\n'
370                   'that purpose.\n'
371                   '\n'
372                   'Typical contents for this file would '
373                   'include an overview of the project, '
374                   'basic\n'
375                   'usage examples, etc. Generally, including '
376                   'the project changelog in here is not\n'
377                   'a good idea, although a simple "What\'s '
378                   'New" section for the most recent version\n'
379                   'may be appropriate.',
380    'description_content_type': None,
381    'docs_url': None,
382    'download_url': 'UNKNOWN',
383    'downloads': {...},
384    'home_page': 'https://github.com/pypa/sampleproject',
385    'keywords': 'sample setuptools development',
386    'license': 'MIT',
387    'maintainer': None,
388    'maintainer_email': None,
389    'name': 'sampleproject',
390    'package_url': 'https://pypi.org/project/sampleproject/',
391    'platform': 'UNKNOWN',
392    'project_url': 'https://pypi.org/project/sampleproject/',
393    'project_urls': {...},
394    'release_url': 'https://pypi.org/project/sampleproject/1.2.0/',
395    'requires_dist': None,
396    'requires_python': None,
397    'summary': 'A sample Python project',
398    'version': '1.2.0'}
399