diff options
author | Victor Stinner <vstinner@python.org> | 2021-10-13 15:35:21 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-13 15:35:21 (GMT) |
commit | 676201a59f90caace606d11d4172aa74c1cd4992 (patch) | |
tree | 50cafc224f0bebf5ecb386caea9fd518aca5b4d0 /Lib/test | |
parent | 713bb19356bce9b8f2b95461834fe1dae505f889 (diff) | |
download | cpython-676201a59f90caace606d11d4172aa74c1cd4992.zip cpython-676201a59f90caace606d11d4172aa74c1cd4992.tar.gz cpython-676201a59f90caace606d11d4172aa74c1cd4992.tar.bz2 |
bpo-45410: regrtest replaces print_warning.orig_stderr (GH-28926)
When running Python tests with -W, runtest() now replaces
support.print_warning.orig_stderr to preserve the messages order.
Add an unit test.
Diffstat (limited to 'Lib/test')
-rw-r--r-- | Lib/test/libregrtest/runtest.py | 9 | ||||
-rw-r--r-- | Lib/test/libregrtest/save_env.py | 7 | ||||
-rw-r--r-- | Lib/test/test_regrtest.py | 40 |
3 files changed, 53 insertions, 3 deletions
diff --git a/Lib/test/libregrtest/runtest.py b/Lib/test/libregrtest/runtest.py index 6fb996a..2397041 100644 --- a/Lib/test/libregrtest/runtest.py +++ b/Lib/test/libregrtest/runtest.py @@ -196,10 +196,18 @@ def _runtest(ns: Namespace, test_name: str) -> TestResult: stream = io.StringIO() orig_stdout = sys.stdout orig_stderr = sys.stderr + print_warning = support.print_warning + orig_print_warnings_stderr = print_warning.orig_stderr + output = None try: sys.stdout = stream sys.stderr = stream + # print_warning() writes into the temporary stream to preserve + # messages order. If support.environment_altered becomes true, + # warnings will be written to sys.stderr below. + print_warning.orig_stderr = stream + result = _runtest_inner(ns, test_name, display_failure=False) if not isinstance(result, Passed): @@ -207,6 +215,7 @@ def _runtest(ns: Namespace, test_name: str) -> TestResult: finally: sys.stdout = orig_stdout sys.stderr = orig_stderr + print_warning.orig_stderr = orig_print_warnings_stderr if output is not None: sys.stderr.write(output) diff --git a/Lib/test/libregrtest/save_env.py b/Lib/test/libregrtest/save_env.py index f0bfcf3..60c9be2 100644 --- a/Lib/test/libregrtest/save_env.py +++ b/Lib/test/libregrtest/save_env.py @@ -320,7 +320,8 @@ class saved_test_environment: support.environment_altered = True restore(original) if not self.quiet and not self.pgo: - print_warning(f"{name} was modified by {self.testname}") - print(f" Before: {original}\n After: {current} ", - file=sys.stderr, flush=True) + print_warning( + f"{name} was modified by {self.testname}\n" + f" Before: {original}\n" + f" After: {current} ") return False diff --git a/Lib/test/test_regrtest.py b/Lib/test/test_regrtest.py index 3780fee..dcc795d 100644 --- a/Lib/test/test_regrtest.py +++ b/Lib/test/test_regrtest.py @@ -1300,6 +1300,46 @@ class ArgsTestCase(BaseTestCase): self.assertIn("Warning -- Uncaught thread exception", output) self.assertIn("Exception: bug in thread", output) + def test_print_warning(self): + # bpo-45410: The order of messages must be preserved when -W and + # support.print_warning() are used. + code = textwrap.dedent(r""" + import sys + import unittest + from test import support + + class MyObject: + pass + + def func_bug(): + raise Exception("bug in thread") + + class Tests(unittest.TestCase): + def test_print_warning(self): + print("msg1: stdout") + support.print_warning("msg2: print_warning") + # Fail with ENV CHANGED to see print_warning() log + support.environment_altered = True + """) + testname = self.create_test(code=code) + + # Expect an output like: + # + # test_threading_excepthook (test.test_x.Tests) ... msg1: stdout + # Warning -- msg2: print_warning + # ok + regex = (r"test_print_warning.*msg1: stdout\n" + r"Warning -- msg2: print_warning\n" + r"ok\n") + for option in ("-v", "-W"): + with self.subTest(option=option): + cmd = ["--fail-env-changed", option, testname] + output = self.run_tests(*cmd, exitcode=3) + self.check_executed_tests(output, [testname], + env_changed=[testname], + fail_env_changed=True) + self.assertRegex(output, regex) + def test_unicode_guard_env(self): guard = os.environ.get(setup.UNICODE_GUARD_ENV) self.assertIsNotNone(guard, f"{setup.UNICODE_GUARD_ENV} not set") |