Skip to content

Commit aab1899

Browse files
authored
bpo-41546: make pprint (like print) not write to stdout when it is None (GH-26810)
1 parent 2c20558 commit aab1899

File tree

4 files changed

+26
-28
lines changed

4 files changed

+26
-28
lines changed

Doc/library/pprint.rst

+14-26
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ The :mod:`pprint` module defines one class:
4646

4747
*stream* (default ``sys.stdout``) is a :term:`file-like object` to
4848
which the output will be written by calling its :meth:`write` method.
49+
If both *stream* and ``sys.stdout`` are ``None``, then
50+
:meth:`~PrettyPrinter.pprint` silently returns.
4951

5052
Other values configure the manner in which nesting of complex data
5153
structures is displayed.
@@ -84,6 +86,9 @@ The :mod:`pprint` module defines one class:
8486
.. versionchanged:: 3.10
8587
Added the *underscore_numbers* parameter.
8688

89+
.. versionchanged:: 3.11
90+
No longer attempts to write to ``sys.stdout`` if it is ``None``.
91+
8792
>>> import pprint
8893
>>> stuff = ['spam', 'eggs', 'lumberjack', 'knights', 'ni']
8994
>>> stuff.insert(0, stuff[:])
@@ -107,24 +112,13 @@ The :mod:`pprint` module defines one class:
107112
>>> pp.pprint(tup)
108113
('spam', ('eggs', ('lumberjack', ('knights', ('ni', ('dead', (...)))))))
109114

110-
111-
The :mod:`pprint` module also provides several shortcut functions:
112-
113115
.. function:: pformat(object, indent=1, width=80, depth=None, *, \
114116
compact=False, sort_dicts=True, underscore_numbers=False)
115117

116118
Return the formatted representation of *object* as a string. *indent*,
117-
*width*, *depth*, *compact*, *sort_dicts* and *underscore_numbers* will be passed to the
118-
:class:`PrettyPrinter` constructor as formatting parameters.
119-
120-
.. versionchanged:: 3.4
121-
Added the *compact* parameter.
122-
123-
.. versionchanged:: 3.8
124-
Added the *sort_dicts* parameter.
125-
126-
.. versionchanged:: 3.10
127-
Added the *underscore_numbers* parameter.
119+
*width*, *depth*, *compact*, *sort_dicts* and *underscore_numbers* are
120+
passed to the :class:`PrettyPrinter` constructor as formatting parameters
121+
and their meanings are as described in its documentation above.
128122

129123

130124
.. function:: pp(object, *args, sort_dicts=False, **kwargs)
@@ -142,20 +136,15 @@ The :mod:`pprint` module also provides several shortcut functions:
142136
compact=False, sort_dicts=True, underscore_numbers=False)
143137

144138
Prints the formatted representation of *object* on *stream*, followed by a
145-
newline. If *stream* is ``None``, ``sys.stdout`` is used. This may be used
139+
newline. If *stream* is ``None``, ``sys.stdout`` is used. This may be used
146140
in the interactive interpreter instead of the :func:`print` function for
147141
inspecting values (you can even reassign ``print = pprint.pprint`` for use
148-
within a scope). *indent*, *width*, *depth*, *compact*, *sort_dicts* and *underscore_numbers* will
149-
be passed to the :class:`PrettyPrinter` constructor as formatting parameters.
150-
151-
.. versionchanged:: 3.4
152-
Added the *compact* parameter.
153-
154-
.. versionchanged:: 3.8
155-
Added the *sort_dicts* parameter.
142+
within a scope).
156143

157-
.. versionchanged:: 3.10
158-
Added the *underscore_numbers* parameter.
144+
The configuration parameters *stream*, *indent*, *width*, *depth*,
145+
*compact*, *sort_dicts* and *underscore_numbers* are passed to the
146+
:class:`PrettyPrinter` constructor and their meanings are as
147+
described in its documentation above.
159148

160149
>>> import pprint
161150
>>> stuff = ['spam', 'eggs', 'lumberjack', 'knights', 'ni']
@@ -168,7 +157,6 @@ The :mod:`pprint` module also provides several shortcut functions:
168157
'knights',
169158
'ni']
170159

171-
172160
.. function:: isreadable(object)
173161

174162
.. index:: builtin: eval

Lib/pprint.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,9 @@ def __init__(self, indent=1, width=80, depth=None, stream=None, *,
148148
self._underscore_numbers = underscore_numbers
149149

150150
def pprint(self, object):
151-
self._format(object, self._stream, 0, 0, {}, 0)
152-
self._stream.write("\n")
151+
if self._stream is not None:
152+
self._format(object, self._stream, 0, 0, {}, 0)
153+
self._stream.write("\n")
153154

154155
def pformat(self, object):
155156
sio = _StringIO()

Lib/test/test_pprint.py

+8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# -*- coding: utf-8 -*-
22

33
import collections
4+
import contextlib
45
import dataclasses
56
import io
67
import itertools
@@ -159,6 +160,13 @@ def test_basic(self):
159160
self.assertTrue(pp.isreadable(safe),
160161
"expected isreadable for %r" % (safe,))
161162

163+
def test_stdout_is_None(self):
164+
with contextlib.redirect_stdout(None):
165+
# smoke test - there is no output to check
166+
value = 'this should not fail'
167+
pprint.pprint(value)
168+
pprint.PrettyPrinter().pprint(value)
169+
162170
def test_knotted(self):
163171
# Verify .isrecursive() and .isreadable() w/ recursion
164172
# Tie a knot.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Make :mod:`pprint` (like the builtin ``print``) not attempt to write to ``stdout`` when it is ``None``.

0 commit comments

Comments
 (0)