From 69741ecc46f368afa90b8578597727bfc2ad2c71 Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Sun, 20 Jun 2021 14:57:07 +0100 Subject: [PATCH 1/7] bpo-41546: pprint (like print) does not write to stdout when it is None --- Lib/pprint.py | 7 ++++++- Lib/test/test_pprint.py | 8 ++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/Lib/pprint.py b/Lib/pprint.py index 13819f3fef212a..91eb79ca254550 100644 --- a/Lib/pprint.py +++ b/Lib/pprint.py @@ -141,8 +141,13 @@ def __init__(self, indent=1, width=80, depth=None, stream=None, *, self._width = width if stream is not None: self._stream = stream - else: + elif _sys.stdout is not None: self._stream = _sys.stdout + else: + class _NullStdout: + def write(self, s): + return 0 + self._stream = _NullStdout() self._compact = bool(compact) self._sort_dicts = sort_dicts self._underscore_numbers = underscore_numbers diff --git a/Lib/test/test_pprint.py b/Lib/test/test_pprint.py index 6c714fd39e203a..606ce101fde634 100644 --- a/Lib/test/test_pprint.py +++ b/Lib/test/test_pprint.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- import collections +import contextlib import dataclasses import io import itertools @@ -159,6 +160,10 @@ def test_basic(self): self.assertTrue(pp.isreadable(safe), "expected isreadable for %r" % (safe,)) + def test_stdout_is_None(self): + with contextlib.redirect_stdout(None): + pprint.pprint('this should not fail') + def test_knotted(self): # Verify .isrecursive() and .isreadable() w/ recursion # Tie a knot. @@ -241,6 +246,9 @@ def test_same_as_repr(self): .replace('\n', ' '), native) self.assertEqual(pprint.pformat(simple, underscore_numbers=True), native) self.assertEqual(pprint.saferepr(simple), native) + with contextlib.redirect_stdout(None): + # smoke test - there is no output to check + pprint.pprint(simple) def test_container_repr_override_called(self): N = 1000 From 793fba502c8750ef10fadcdcb6f078ffc94b95d0 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Sun, 20 Jun 2021 14:03:19 +0000 Subject: [PATCH 2/7] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../NEWS.d/next/Library/2021-06-20-14-03-18.bpo-41546.lO1jXU.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2021-06-20-14-03-18.bpo-41546.lO1jXU.rst diff --git a/Misc/NEWS.d/next/Library/2021-06-20-14-03-18.bpo-41546.lO1jXU.rst b/Misc/NEWS.d/next/Library/2021-06-20-14-03-18.bpo-41546.lO1jXU.rst new file mode 100644 index 00000000000000..daca2ee3bb0a9c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-06-20-14-03-18.bpo-41546.lO1jXU.rst @@ -0,0 +1 @@ +Make :mod:`pprint` (like the builtin ``print``) not write to ``stdout`` when it is ``None``. \ No newline at end of file From 214fb4fbc6ad8d1b6a8fc4a027c42baf4f333d24 Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Sun, 20 Jun 2021 21:05:22 +0100 Subject: [PATCH 3/7] skip formatting altogether if stdout is None --- Lib/pprint.py | 12 ++++-------- Lib/test/test_pprint.py | 5 ++++- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/Lib/pprint.py b/Lib/pprint.py index 91eb79ca254550..60ce57e910ec49 100644 --- a/Lib/pprint.py +++ b/Lib/pprint.py @@ -141,20 +141,16 @@ def __init__(self, indent=1, width=80, depth=None, stream=None, *, self._width = width if stream is not None: self._stream = stream - elif _sys.stdout is not None: - self._stream = _sys.stdout else: - class _NullStdout: - def write(self, s): - return 0 - self._stream = _NullStdout() + self._stream = _sys.stdout self._compact = bool(compact) self._sort_dicts = sort_dicts self._underscore_numbers = underscore_numbers def pprint(self, object): - self._format(object, self._stream, 0, 0, {}, 0) - self._stream.write("\n") + if self._stream is not None: + self._format(object, self._stream, 0, 0, {}, 0) + self._stream.write("\n") def pformat(self, object): sio = _StringIO() diff --git a/Lib/test/test_pprint.py b/Lib/test/test_pprint.py index 606ce101fde634..d98032cccc2238 100644 --- a/Lib/test/test_pprint.py +++ b/Lib/test/test_pprint.py @@ -162,7 +162,10 @@ def test_basic(self): def test_stdout_is_None(self): with contextlib.redirect_stdout(None): - pprint.pprint('this should not fail') + # smoke test - there is no output to check + value = 'this should not fail' + pprint.pprint(value) + pprint.PrettyPrinter().pprint(value) def test_knotted(self): # Verify .isrecursive() and .isreadable() w/ recursion From be4404e18f43b8901a18d5ed68d8b8cfef8abef4 Mon Sep 17 00:00:00 2001 From: Irit Katriel <1055913+iritkatriel@users.noreply.github.com> Date: Fri, 2 Jul 2021 11:28:30 +0100 Subject: [PATCH 4/7] edit news --- .../next/Library/2021-06-20-14-03-18.bpo-41546.lO1jXU.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2021-06-20-14-03-18.bpo-41546.lO1jXU.rst b/Misc/NEWS.d/next/Library/2021-06-20-14-03-18.bpo-41546.lO1jXU.rst index daca2ee3bb0a9c..050da761570d42 100644 --- a/Misc/NEWS.d/next/Library/2021-06-20-14-03-18.bpo-41546.lO1jXU.rst +++ b/Misc/NEWS.d/next/Library/2021-06-20-14-03-18.bpo-41546.lO1jXU.rst @@ -1 +1 @@ -Make :mod:`pprint` (like the builtin ``print``) not write to ``stdout`` when it is ``None``. \ No newline at end of file +Make :mod:`pprint` (like the builtin ``print``) not attempt to write to ``stdout`` when it is ``None``. From db4e47157bec958a58ffbf222ec11af9dcb3452c Mon Sep 17 00:00:00 2001 From: Irit Katriel <1055913+iritkatriel@users.noreply.github.com> Date: Sat, 3 Jul 2021 14:52:38 +0100 Subject: [PATCH 5/7] Remove redundant test --- Lib/test/test_pprint.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/Lib/test/test_pprint.py b/Lib/test/test_pprint.py index d98032cccc2238..c7b9893943471f 100644 --- a/Lib/test/test_pprint.py +++ b/Lib/test/test_pprint.py @@ -249,9 +249,6 @@ def test_same_as_repr(self): .replace('\n', ' '), native) self.assertEqual(pprint.pformat(simple, underscore_numbers=True), native) self.assertEqual(pprint.saferepr(simple), native) - with contextlib.redirect_stdout(None): - # smoke test - there is no output to check - pprint.pprint(simple) def test_container_repr_override_called(self): N = 1000 From 62af033e5e621a84b26bb032b914ec5a3adbf39e Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Sat, 3 Jul 2021 16:37:04 +0100 Subject: [PATCH 6/7] mention the change in the docs. Remove repetition of version directives for shared parameters. --- Doc/library/pprint.rst | 40 ++++++++++++++-------------------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/Doc/library/pprint.rst b/Doc/library/pprint.rst index 8f374503725ad1..aa9a83bad7b661 100644 --- a/Doc/library/pprint.rst +++ b/Doc/library/pprint.rst @@ -46,6 +46,8 @@ The :mod:`pprint` module defines one class: *stream* (default ``sys.stdout``) is a :term:`file-like object` to which the output will be written by calling its :meth:`write` method. + If both *stream* and ``sys.stdout`` are ``None``, then + :meth:`~PrettyPrinter.pprint` silently returns. Other values configure the manner in which nesting of complex data structures is displayed. @@ -84,6 +86,9 @@ The :mod:`pprint` module defines one class: .. versionchanged:: 3.10 Added the *underscore_numbers* parameter. + .. versionchanged:: 3.11 + No longer attempts to write to ``sys.stdout`` if it is None. + >>> import pprint >>> stuff = ['spam', 'eggs', 'lumberjack', 'knights', 'ni'] >>> stuff.insert(0, stuff[:]) @@ -107,24 +112,13 @@ The :mod:`pprint` module defines one class: >>> pp.pprint(tup) ('spam', ('eggs', ('lumberjack', ('knights', ('ni', ('dead', (...))))))) - -The :mod:`pprint` module also provides several shortcut functions: - .. function:: pformat(object, indent=1, width=80, depth=None, *, \ compact=False, sort_dicts=True, underscore_numbers=False) Return the formatted representation of *object* as a string. *indent*, - *width*, *depth*, *compact*, *sort_dicts* and *underscore_numbers* will be passed to the - :class:`PrettyPrinter` constructor as formatting parameters. - - .. versionchanged:: 3.4 - Added the *compact* parameter. - - .. versionchanged:: 3.8 - Added the *sort_dicts* parameter. - - .. versionchanged:: 3.10 - Added the *underscore_numbers* parameter. + *width*, *depth*, *compact*, *sort_dicts* and *underscore_numbers* are + passed to the :class:`PrettyPrinter` constructor as formatting parameters + and their meanings are as described in its documentation above. .. function:: pp(object, *args, sort_dicts=False, **kwargs) @@ -142,20 +136,15 @@ The :mod:`pprint` module also provides several shortcut functions: compact=False, sort_dicts=True, underscore_numbers=False) Prints the formatted representation of *object* on *stream*, followed by a - newline. If *stream* is ``None``, ``sys.stdout`` is used. This may be used + newline. If *stream* is ``None``, ``sys.stdout`` is used. This may be used in the interactive interpreter instead of the :func:`print` function for inspecting values (you can even reassign ``print = pprint.pprint`` for use - within a scope). *indent*, *width*, *depth*, *compact*, *sort_dicts* and *underscore_numbers* will - be passed to the :class:`PrettyPrinter` constructor as formatting parameters. - - .. versionchanged:: 3.4 - Added the *compact* parameter. - - .. versionchanged:: 3.8 - Added the *sort_dicts* parameter. + within a scope). - .. versionchanged:: 3.10 - Added the *underscore_numbers* parameter. + The configuration parameters *stream*, *indent*, *width*, *depth*, + *compact*, *sort_dicts* and *underscore_numbers* are passed to the + :class:`PrettyPrinter` constructor and their meanings are as + described in its documentation above. >>> import pprint >>> stuff = ['spam', 'eggs', 'lumberjack', 'knights', 'ni'] @@ -168,7 +157,6 @@ The :mod:`pprint` module also provides several shortcut functions: 'knights', 'ni'] - .. function:: isreadable(object) .. index:: builtin: eval From fba7e434d2a4083115defd015ce76a8a0f8a5886 Mon Sep 17 00:00:00 2001 From: Irit Katriel <1055913+iritkatriel@users.noreply.github.com> Date: Sun, 18 Jul 2021 21:45:02 +0100 Subject: [PATCH 7/7] Update Doc/library/pprint.rst to add backticks around None Co-authored-by: Serhiy Storchaka --- Doc/library/pprint.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/pprint.rst b/Doc/library/pprint.rst index aa9a83bad7b661..3da5aa9389b17d 100644 --- a/Doc/library/pprint.rst +++ b/Doc/library/pprint.rst @@ -87,7 +87,7 @@ The :mod:`pprint` module defines one class: Added the *underscore_numbers* parameter. .. versionchanged:: 3.11 - No longer attempts to write to ``sys.stdout`` if it is None. + No longer attempts to write to ``sys.stdout`` if it is ``None``. >>> import pprint >>> stuff = ['spam', 'eggs', 'lumberjack', 'knights', 'ni']