summaryrefslogtreecommitdiffstats
path: root/Lib/test
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2021-10-13 15:35:21 (GMT)
committerGitHub <noreply@github.com>2021-10-13 15:35:21 (GMT)
commit676201a59f90caace606d11d4172aa74c1cd4992 (patch)
tree50cafc224f0bebf5ecb386caea9fd518aca5b4d0 /Lib/test
parent713bb19356bce9b8f2b95461834fe1dae505f889 (diff)
downloadcpython-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.py9
-rw-r--r--Lib/test/libregrtest/save_env.py7
-rw-r--r--Lib/test/test_regrtest.py40
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")