gh-67217: Test both warnings implementations in environment variable tests (GH-155234)

serhiy-storchaka <[email protected]>
Newsgroups gmane.comp.python.cvs
Message-ID <[email protected]>
https://github.com/python/cpython/commit/bf2c0539334877ce4bfb2b3c6a36248a0ef52d72
commit: bf2c0539334877ce4bfb2b3c6a36248a0ef52d72
branch: main
author: Serhiy Storchaka <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2026-08-17T21:58:29+03:00
summary:

gh-67217: Test both warnings implementations in environment variable tests (GH-155234)

The code executed in the subprocess now disables the C implementation when
the Python implementation is tested.

Tests which only check sys.warnoptions do not depend on the implementation.
They are moved to a separate test class and use the runInSubprocess()
decorator.

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>

files:
M Lib/test/test_warnings/__init__.py

diff --git a/Lib/test/test_warnings/__init__.py b/Lib/test/test_warnings/__init__.py
index cde6076dd2f44b7..b86a8838c7a2457 100644
--- a/Lib/test/test_warnings/__init__.py
+++ b/Lib/test/test_warnings/__init__.py
@@ -13,6 +13,7 @@
 import unittest
 from test import support
 from test.support import import_helper
+from test.support import isolation
 from test.support import os_helper
 from test.support import warnings_helper
 from test.support import force_not_colorized
@@ -1518,49 +1519,74 @@ class PyCatchWarningTests(CatchWarningTests, unittest.TestCase):
     module = py_warnings
 
 
-class EnvironmentVariableTests(BaseTest):
+_NONASCII_WARNOPTION = 'ignore:DeprecationWarning' + os_helper.FS_NONASCII
+
+
+class WarnOptionsTests(unittest.TestCase):
+    """Tests of the -W option and the PYTHONWARNINGS environment variable.
+
+    sys.warnoptions is set by the interpreter, so these tests do not depend
+    on the used implementation of the warnings module.
+    """
 
+    @isolation.runInSubprocess(
+        env={'PYTHONWARNINGS': 'ignore::DeprecationWarning',
+             'PYTHONDEVMODE': ''})
     def test_single_warning(self):
-        rc, stdout, stderr = assert_python_ok("-c",
-            "import sys; sys.stdout.write(str(sys.warnoptions))",
-            PYTHONWARNINGS="ignore::DeprecationWarning",
-            PYTHONDEVMODE="")
-        self.assertEqual(stdout, b"['ignore::DeprecationWarning']")
+        self.assertEqual(sys.warnoptions, ['ignore::DeprecationWarning'])
 
+    @isolation.runInSubprocess(
+        env={'PYTHONWARNINGS': 'ignore::DeprecationWarning,'
+                               'ignore::UnicodeWarning',
+             'PYTHONDEVMODE': ''})
     def test_comma_separated_warnings(self):
-        rc, stdout, stderr = assert_python_ok("-c",
-            "import sys; sys.stdout.write(str(sys.warnoptions))",
-            PYTHONWARNINGS="ignore::DeprecationWarning,ignore::UnicodeWarning",
-            PYTHONDEVMODE="")
-        self.assertEqual(stdout,
-            b"['ignore::DeprecationWarning', 'ignore::UnicodeWarning']")
+        self.assertEqual(sys.warnoptions, ['ignore::DeprecationWarning',
+                                           'ignore::UnicodeWarning'])
 
-    @force_not_colorized
+    @isolation.runInSubprocess(
+        options=['-Wignore::UnicodeWarning'],
+        env={'PYTHONWARNINGS': 'ignore::DeprecationWarning',
+             'PYTHONDEVMODE': ''})
     def test_envvar_and_command_line(self):
-        rc, stdout, stderr = assert_python_ok("-Wignore::UnicodeWarning", "-c",
-            "import sys; sys.stdout.write(str(sys.warnoptions))",
-            PYTHONWARNINGS="ignore::DeprecationWarning",
-            PYTHONDEVMODE="")
-        self.assertEqual(stdout,
-            b"['ignore::DeprecationWarning', 'ignore::UnicodeWarning']")
+        self.assertEqual(sys.warnoptions, ['ignore::DeprecationWarning',
+                                           'ignore::UnicodeWarning'])
+
+    @unittest.skipUnless(sys.getfilesystemencoding() != 'ascii',
+                         'requires non-ascii filesystemencoding')
+    @isolation.runInSubprocess(
+        env={'PYTHONWARNINGS': _NONASCII_WARNOPTION,
+             'PYTHONDEVMODE': ''})
+    def test_nonascii(self):
+        self.assertEqual(sys.warnoptions, [_NONASCII_WARNOPTION])
+
+
+class EnvironmentVariableTests(BaseTest):
+
+    def prepare_code(self, code):
+        """Make the subprocess use the tested implementation."""
+        if self.module is py_warnings:
+            # Disable the warnings acceleration module in the subprocess.
+            code = ("import sys; sys.modules.pop('warnings', None); "
+                    "sys.modules['_warnings'] = None; ") + code
+        return code
 
     @force_not_colorized
     def test_conflicting_envvar_and_command_line(self):
-        rc, stdout, stderr = assert_python_failure("-Werror::DeprecationWarning", "-c",
+        code = self.prepare_code(
             "import sys, warnings; sys.stdout.write(str(sys.warnoptions)); "
-            "warnings.warn('Message', DeprecationWarning)",
+            "warnings.warn('Message', DeprecationWarning)")
+        rc, stdout, stderr = assert_python_failure(
+            "-Werror::DeprecationWarning", "-c", code,
             PYTHONWARNINGS="default::DeprecationWarning",
             PYTHONDEVMODE="")
         self.assertEqual(stdout,
             b"['default::DeprecationWarning', 'error::DeprecationWarning']")
-        self.assertEqual(stderr.splitlines(),
-            [b"Traceback (most recent call last):",
-             b"  File \"<string>\", line 1, in <module>",
-             b'    import sys, warnings; sys.stdout.write(str(sys.warnoptions)); warnings.w'
-             b"arn('Message', DeprecationWarning)",
-             b'                                                                  ~~~~~~~~~~'
-             b'~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^',
-             b"DeprecationWarning: Message"])
+        # The traceback of the Python implementation contains additional
+        # frames, so only the ends of the traceback are checked.
+        lines = stderr.splitlines()
+        self.assertEqual(lines[0], b"Traceback (most recent call last):")
+        self.assertEqual(lines[1], b'  File "<string>", line 1, in <module>')
+        self.assertEqual(lines[-1], b"DeprecationWarning: Message")
 
     def test_default_filter_configuration(self):
         pure_python_api = self.module is py_warnings
@@ -1580,12 +1606,8 @@ def test_default_filter_configuration(self):
             ]
         expected_output = [str(f).encode() for f in expected_default_filters]
 
-        if pure_python_api:
-            # Disable the warnings acceleration module in the subprocess
-            code = "import sys; sys.modules.pop('warnings', None); sys.modules['_warnings'] = None; "
-        else:
-            code = ""
-        code += "import warnings; [print(f) for f in warnings._get_filters()]"
+        code = self.prepare_code(
+            "import warnings; [print(f) for f in warnings._get_filters()]")
 
         rc, stdout, stderr = assert_python_ok("-c", code, __isolated=True)
         stdout_lines = [line.strip() for line in stdout.splitlines()]
@@ -1593,17 +1615,6 @@ def test_default_filter_configuration(self):
         self.assertEqual(stdout_lines, expected_output)
 
 
-    @unittest.skipUnless(sys.getfilesystemencoding() != 'ascii',
-                         'requires non-ascii filesystemencoding')
-    def test_nonascii(self):
-        PYTHONWARNINGS="ignore:DeprecationWarning" + os_helper.FS_NONASCII
-        rc, stdout, stderr = assert_python_ok("-c",
-            "import sys; sys.stdout.write(str(sys.warnoptions))",
-            PYTHONIOENCODING="utf-8",
-            PYTHONWARNINGS=PYTHONWARNINGS,
-            PYTHONDEVMODE="")
-        self.assertEqual(stdout, str([PYTHONWARNINGS]).encode())
-
 class CEnvironmentVariableTests(EnvironmentVariableTests, unittest.TestCase):
     module = c_warnings
 

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.