From d4abe3be6559c6cd20d1c24f6ceb206c507c458e Mon Sep 17 00:00:00 2001 From: Cody Maloney Date: Wed, 29 Oct 2025 05:33:44 -0700 Subject: [PATCH] gh-140082: Forward colorizing from libregrtest to unittest (GH-140083) libregrtest redirects test output to a file as part of its operation. When `unittest` checks to see if it should colorize with `isatty(sys.stdout)` that fails resulting in no colorizing of the unittest output. Update `libregrtest` to set `FORCE_COLOR=1` when redirecting test output so that unittest will do color printing. (cherry picked from commit 6ff62ac4fbc3f17529823c146cc3a3f8c21eed42) Co-authored-by: Cody Maloney Co-authored-by: Victor Stinner --- Lib/test/libregrtest/setup.py | 8 ++++++++ Lib/test/libregrtest/worker.py | 7 +++++++ .../Tests/2025-10-15-00-52-12.gh-issue-140082.fpET50.rst | 3 +++ 3 files changed, 18 insertions(+) create mode 100644 Misc/NEWS.d/next/Tests/2025-10-15-00-52-12.gh-issue-140082.fpET50.rst diff --git a/Lib/test/libregrtest/setup.py b/Lib/test/libregrtest/setup.py index ec6f2fab2bb506..d50b2155a6bf04 100644 --- a/Lib/test/libregrtest/setup.py +++ b/Lib/test/libregrtest/setup.py @@ -8,6 +8,7 @@ import unittest from test import support from test.support.os_helper import TESTFN_UNDECODABLE, FS_NONASCII +from _colorize import can_colorize # type: ignore[import-not-found] from .filter import set_match_tests from .runtests import RunTests @@ -141,3 +142,10 @@ def setup_tests(runtests: RunTests) -> None: gc.set_threshold(runtests.gc_threshold) random.seed(runtests.random_seed) + + # sys.stdout is redirected to a StringIO in single process mode on which + # color auto-detect fails as StringIO is not a TTY. If the original + # sys.stdout supports color pass that through with FORCE_COLOR so that when + # results are printed, such as with -W, they get color. + if can_colorize(file=sys.stdout): + os.environ['FORCE_COLOR'] = "1" diff --git a/Lib/test/libregrtest/worker.py b/Lib/test/libregrtest/worker.py index d232ea69483277..e0627c4adc0107 100644 --- a/Lib/test/libregrtest/worker.py +++ b/Lib/test/libregrtest/worker.py @@ -1,6 +1,7 @@ import subprocess import sys import os +from _colorize import can_colorize # type: ignore[import-not-found] from typing import Any, NoReturn from test.support import os_helper, Py_DEBUG @@ -29,6 +30,12 @@ def create_worker_process(runtests: WorkerRunTests, output_fd: int, env['TEMP'] = tmp_dir env['TMP'] = tmp_dir + # The subcommand is run with a temporary output which means it is not a TTY + # and won't auto-color. The test results are printed to stdout so if we can + # color that have the subprocess use color. + if can_colorize(file=sys.stdout): + env['FORCE_COLOR'] = '1' + # Running the child from the same working directory as regrtest's original # invocation ensures that TEMPDIR for the child is the same when # sysconfig.is_python_build() is true. See issue 15300. diff --git a/Misc/NEWS.d/next/Tests/2025-10-15-00-52-12.gh-issue-140082.fpET50.rst b/Misc/NEWS.d/next/Tests/2025-10-15-00-52-12.gh-issue-140082.fpET50.rst new file mode 100644 index 00000000000000..70e70218254488 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2025-10-15-00-52-12.gh-issue-140082.fpET50.rst @@ -0,0 +1,3 @@ +Update ``python -m test`` to set ``FORCE_COLOR=1`` when being run with color +enabled so that :mod:`unittest` which is run by it with redirected output will +output in color.