gh-117225: Add color to doctest output (#117583)

Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
This commit is contained in:
Hugo van Kemenade 2024-04-24 14:27:40 +03:00 committed by GitHub
parent f6e5cc66be
commit 975081b11e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 92 additions and 15 deletions

View file

@ -16,6 +16,7 @@ import unittest
import tempfile
import types
import contextlib
import traceback
def doctest_skip_if(condition):
@ -470,7 +471,7 @@ We'll simulate a __file__ attr that ends in pyc:
>>> tests = finder.find(sample_func)
>>> print(tests) # doctest: +ELLIPSIS
[<DocTest sample_func from test_doctest.py:37 (1 example)>]
[<DocTest sample_func from test_doctest.py:38 (1 example)>]
The exact name depends on how test_doctest was invoked, so allow for
leading path components.
@ -892,6 +893,9 @@ Unit tests for the `DocTestRunner` class.
DocTestRunner is used to run DocTest test cases, and to accumulate
statistics. Here's a simple DocTest case we can use:
>>> save_colorize = traceback._COLORIZE
>>> traceback._COLORIZE = False
>>> def f(x):
... '''
... >>> x = 12
@ -946,6 +950,8 @@ the failure and proceeds to the next example:
6
ok
TestResults(failed=1, attempted=3)
>>> traceback._COLORIZE = save_colorize
"""
def verbose_flag(): r"""
The `verbose` flag makes the test runner generate more detailed
@ -1021,6 +1027,9 @@ An expected exception is specified with a traceback message. The
lines between the first line and the type/value may be omitted or
replaced with any other string:
>>> save_colorize = traceback._COLORIZE
>>> traceback._COLORIZE = False
>>> def f(x):
... '''
... >>> x = 12
@ -1251,6 +1260,8 @@ unexpected exception:
...
ZeroDivisionError: integer division or modulo by zero
TestResults(failed=1, attempted=1)
>>> traceback._COLORIZE = save_colorize
"""
def displayhook(): r"""
Test that changing sys.displayhook doesn't matter for doctest.
@ -1292,6 +1303,9 @@ together).
The DONT_ACCEPT_TRUE_FOR_1 flag disables matches between True/False
and 1/0:
>>> save_colorize = traceback._COLORIZE
>>> traceback._COLORIZE = False
>>> def f(x):
... '>>> True\n1\n'
@ -1711,6 +1725,7 @@ more than one flag value. Here we verify that's fixed:
Clean up.
>>> del doctest.OPTIONFLAGS_BY_NAME[unlikely]
>>> traceback._COLORIZE = save_colorize
"""
@ -1721,6 +1736,9 @@ Option directives can be used to turn option flags on or off for a
single example. To turn an option on for an example, follow that
example with a comment of the form ``# doctest: +OPTION``:
>>> save_colorize = traceback._COLORIZE
>>> traceback._COLORIZE = False
>>> def f(x): r'''
... >>> print(list(range(10))) # should fail: no ellipsis
... [0, 1, ..., 9]
@ -1928,6 +1946,8 @@ source:
>>> test = doctest.DocTestParser().get_doctest(s, {}, 's', 's.py', 0)
Traceback (most recent call last):
ValueError: line 0 of the doctest for s has an option directive on a line with no example: '# doctest: +ELLIPSIS'
>>> traceback._COLORIZE = save_colorize
"""
def test_testsource(): r"""
@ -2011,6 +2031,9 @@ if not hasattr(sys, 'gettrace') or not sys.gettrace():
with a version that restores stdout. This is necessary for you to
see debugger output.
>>> save_colorize = traceback._COLORIZE
>>> traceback._COLORIZE = False
>>> doc = '''
... >>> x = 42
... >>> raise Exception('clé')
@ -2065,7 +2088,7 @@ if not hasattr(sys, 'gettrace') or not sys.gettrace():
... finally:
... sys.stdin = real_stdin
--Return--
> <doctest test.test_doctest.test_doctest.test_pdb_set_trace[7]>(3)calls_set_trace()->None
> <doctest test.test_doctest.test_doctest.test_pdb_set_trace[9]>(3)calls_set_trace()->None
-> import pdb; pdb.set_trace()
(Pdb) print(y)
2
@ -2133,6 +2156,8 @@ if not hasattr(sys, 'gettrace') or not sys.gettrace():
Got:
9
TestResults(failed=1, attempted=3)
>>> traceback._COLORIZE = save_colorize
"""
def test_pdb_set_trace_nested():
@ -2667,7 +2692,10 @@ doctest examples in a given file. In its simple invocation, it is
called with the name of a file, which is taken to be relative to the
calling module. The return value is (#failures, #tests).
We don't want `-v` in sys.argv for these tests.
We don't want color or `-v` in sys.argv for these tests.
>>> save_colorize = traceback._COLORIZE
>>> traceback._COLORIZE = False
>>> save_argv = sys.argv
>>> if '-v' in sys.argv:
@ -2835,6 +2863,7 @@ Test the verbose output:
TestResults(failed=0, attempted=2)
>>> doctest.master = None # Reset master.
>>> sys.argv = save_argv
>>> traceback._COLORIZE = save_colorize
"""
class TestImporter(importlib.abc.MetaPathFinder, importlib.abc.ResourceLoader):
@ -2972,6 +3001,9 @@ if supports_unicode:
def test_unicode(): """
Check doctest with a non-ascii filename:
>>> save_colorize = traceback._COLORIZE
>>> traceback._COLORIZE = False
>>> doc = '''
... >>> raise Exception('clé')
... '''
@ -2997,8 +3029,11 @@ Check doctest with a non-ascii filename:
raise Exception('clé')
Exception: clé
TestResults(failed=1, attempted=1)
>>> traceback._COLORIZE = save_colorize
"""
@doctest_skip_if(not support.has_subprocess_support)
def test_CLI(): r"""
The doctest module can be used to run doctests against an arbitrary file.
@ -3290,6 +3325,9 @@ def test_run_doctestsuite_multiple_times():
def test_exception_with_note(note):
"""
>>> save_colorize = traceback._COLORIZE
>>> traceback._COLORIZE = False
>>> test_exception_with_note('Note')
Traceback (most recent call last):
...
@ -3339,6 +3377,8 @@ def test_exception_with_note(note):
ValueError: message
note
TestResults(failed=1, attempted=...)
>>> traceback._COLORIZE = save_colorize
"""
exc = ValueError('Text')
exc.add_note(note)
@ -3419,6 +3459,9 @@ def test_syntax_error_subclass_from_stdlib():
def test_syntax_error_with_incorrect_expected_note():
"""
>>> save_colorize = traceback._COLORIZE
>>> traceback._COLORIZE = False
>>> def f(x):
... r'''
... >>> exc = SyntaxError("error", ("x.py", 23, None, "bad syntax"))
@ -3447,6 +3490,8 @@ def test_syntax_error_with_incorrect_expected_note():
note1
note2
TestResults(failed=1, attempted=...)
>>> traceback._COLORIZE = save_colorize
"""