diff --git a/Doc/library/doctest.rst b/Doc/library/doctest.rst index df3de8f622a091..c499024e43ad8a 100644 --- a/Doc/library/doctest.rst +++ b/Doc/library/doctest.rst @@ -1631,6 +1631,10 @@ DocTestRunner objects output checker, and the results are formatted by the :meth:`!DocTestRunner.report_\*` methods. + .. versionchanged:: 3.13 + Added support for testing examples with a customized + :func:`sys.displayhook` value. Previously, this wasn't allowed and + the method was always using the :func:`sys.__displayhook__`. .. method:: summarize(verbose=None) diff --git a/Lib/doctest.py b/Lib/doctest.py index 92a2ab4f7e66f8..bcd7b48531646a 100644 --- a/Lib/doctest.py +++ b/Lib/doctest.py @@ -1565,9 +1565,8 @@ def out(s): self.save_linecache_getlines = linecache.getlines linecache.getlines = self.__patched_linecache_getlines - # Make sure sys.displayhook just prints the value to stdout + # Make sure sys.displayhook restored at the end save_displayhook = sys.displayhook - sys.displayhook = sys.__displayhook__ saved_can_colorize = _colorize.can_colorize _colorize.can_colorize = lambda *args, **kwargs: False color_variables = {"PYTHON_COLORS": None, "FORCE_COLOR": None} diff --git a/Lib/test/test_doctest/test_doctest.py b/Lib/test/test_doctest/test_doctest.py index 0fa74407e3c436..5e624f7e183672 100644 --- a/Lib/test/test_doctest/test_doctest.py +++ b/Lib/test/test_doctest/test_doctest.py @@ -1268,33 +1268,46 @@ def exceptions(): r""" >>> _colorize.COLORIZE = save_colorize """ def displayhook(): r""" -Test that changing sys.displayhook doesn't matter for doctest. +Test changing sys.displayhook. + +Run with a custom displayhook: >>> import sys - >>> orig_displayhook = sys.displayhook >>> def my_displayhook(x): ... print('hi!') + ... sys.__displayhook__(x) >>> sys.displayhook = my_displayhook + >>> 3 + hi! + 3 >>> def f(): ... ''' ... >>> 3 + ... hi! ... 3 ... ''' >>> test = doctest.DocTestFinder().find(f)[0] - >>> r = doctest.DocTestRunner(verbose=False).run(test) - >>> post_displayhook = sys.displayhook - - We need to restore sys.displayhook now, so that we'll be able to test - results. - - >>> sys.displayhook = orig_displayhook + >>> doctest.DocTestRunner(verbose=False).run(test) + hi! + TestResults(failed=0, attempted=1) + >>> sys.displayhook = sys.__displayhook__ + >>> 3 + 3 - Ok, now we can check that everything is ok. +Test changing displayhook in the doctest: - >>> r - TestResults(failed=0, attempted=1) - >>> post_displayhook is my_displayhook - True + >>> def g(): + ... ''' + ... >>> import sys + ... >>> sys.displayhook = lambda x: print('spam') + ... >>> 3 + ... spam + ... ''' + >>> test = doctest.DocTestFinder().find(g)[0] + >>> doctest.DocTestRunner(verbose=False).run(test) + TestResults(failed=0, attempted=3) + >>> 42 + 42 """ def optionflags(): r""" Tests of `DocTestRunner`'s option flag handling. diff --git a/Misc/NEWS.d/next/Library/2021-04-27-08-36-50.bpo-26092.1qLzp5.rst b/Misc/NEWS.d/next/Library/2021-04-27-08-36-50.bpo-26092.1qLzp5.rst new file mode 100644 index 00000000000000..e4c12bdfcf1093 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-04-27-08-36-50.bpo-26092.1qLzp5.rst @@ -0,0 +1,2 @@ +Allow using custom sys.displayhook's with doctest. Patch by Sergey B +Kirpichev.