-
-
Notifications
You must be signed in to change notification settings - Fork 32k
gh-117225: Add color to doctest output #117583
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
2c1108b
Add colour to doctest output and create _colorize module
hugovk d27c0a8
Use _colorize in traceback module
hugovk bb591b6
Fix whitespace
hugovk 42079be
Use f-strings
hugovk 0088579
Remove underscores from members of an underscored module
hugovk d3034fa
Add blurb
hugovk 39780cb
Remove underscores from members of an underscored module
hugovk c5aec15
Revert "Fix whitespace"
hugovk 7e40133
Move _colorize to stdlib block, colour->color
hugovk e484465
Move imports together
hugovk 1c7b025
Move imports together
hugovk ab2c94c
Move imports together
hugovk 1aaeab8
Revert notests -> no_tests
hugovk cd02e4a
Revert "Use f-strings"
hugovk 06543ff
Fix local tests
hugovk 31c6647
Use red divider for failed test
hugovk 9be3d81
Fix local tests
hugovk e4ff3e3
Less red
hugovk b62500a
Revert unnecessary changes
hugovk eb4f8dc
Move colour tests to test__colorize.py
hugovk 976bfb4
Refactor asserts
hugovk ad7a946
Add missing captured_output to test.support's __all__ to fix IDE warning
hugovk 796e9f2
Only move test_colorized_detection_checks_for_environment_variables f…
hugovk 99d4d0c
Apply suggestions from code review
hugovk 95b9831
Use unittest's enterContext
hugovk d5417b4
Merge remote-tracking branch 'upstream/main' into doctest-tidy-output…
hugovk ece3ce0
Keep colorize functionality in traceback module for now
hugovk File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,6 +16,7 @@ | |
import tempfile | ||
import types | ||
import contextlib | ||
import traceback | ||
|
||
|
||
def doctest_skip_if(condition): | ||
|
@@ -470,7 +471,7 @@ def basics(): r""" | |
>>> 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 @@ def basics(): r""" | |
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 @@ def basics(): r""" | |
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 @@ def exceptions(): r""" | |
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 @@ def exceptions(): r""" | |
... | ||
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 @@ def optionflags(): r""" | |
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 @@ def optionflags(): r""" | |
|
||
Clean up. | ||
>>> del doctest.OPTIONFLAGS_BY_NAME[unlikely] | ||
>>> traceback._COLORIZE = save_colorize | ||
|
||
""" | ||
|
||
|
@@ -1721,6 +1736,9 @@ def option_directives(): r""" | |
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 @@ def option_directives(): r""" | |
>>> 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 @@ def test_pdb_set_trace(): | |
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 @@ def test_pdb_set_trace(): | |
... 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 @@ def test_pdb_set_trace(): | |
Got: | ||
9 | ||
TestResults(failed=1, attempted=3) | ||
|
||
>>> traceback._COLORIZE = save_colorize | ||
""" | ||
|
||
def test_pdb_set_trace_nested(): | ||
|
@@ -2652,7 +2677,10 @@ def test_testfile(): r""" | |
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: | ||
|
@@ -2820,6 +2848,7 @@ def test_testfile(): r""" | |
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): | ||
|
@@ -2957,6 +2986,9 @@ def test_testmod(): r""" | |
def test_unicode(): """ | ||
Check doctest with a non-ascii filename: | ||
|
||
>>> save_colorize = traceback._COLORIZE | ||
>>> traceback._COLORIZE = False | ||
|
||
>>> doc = ''' | ||
... >>> raise Exception('clé') | ||
... ''' | ||
|
@@ -2982,8 +3014,11 @@ def test_unicode(): """ | |
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. | ||
|
@@ -3275,6 +3310,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): | ||
... | ||
|
@@ -3324,6 +3362,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) | ||
|
@@ -3404,6 +3444,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")) | ||
|
@@ -3432,6 +3475,8 @@ def test_syntax_error_with_incorrect_expected_note(): | |
note1 | ||
note2 | ||
TestResults(failed=1, attempted=...) | ||
|
||
>>> traceback._COLORIZE = save_colorize | ||
""" | ||
|
||
|
||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 1 addition & 0 deletions
1
Misc/NEWS.d/next/Library/2024-04-06-18-41-36.gh-issue-117225.tJh1Hw.rst
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Add colour to doctest output. Patch by Hugo van Kemenade. |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, is there a reason why these colours might have been omitted from the original changes to colourise Python's tracebacks in general? Maybe to avoid accessibility issues for people who are red-green colourblind? Or to avoid issues for people who have light themes on their terminals?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think because when there's a traceback error there's nothing "good" to report in green :)