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]

Reply via email to