Skip to content

Commit f744e30

Browse files
gh-67217: Test both warnings implementations in environment variable tests
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) <noreply@anthropic.com>
1 parent 1d90627 commit f744e30

1 file changed

Lines changed: 57 additions & 46 deletions

File tree

Lib/test/test_warnings/__init__.py

Lines changed: 57 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import unittest
1414
from test import support
1515
from test.support import import_helper
16+
from test.support import isolation
1617
from test.support import os_helper
1718
from test.support import warnings_helper
1819
from test.support import force_not_colorized
@@ -1518,49 +1519,74 @@ class PyCatchWarningTests(CatchWarningTests, unittest.TestCase):
15181519
module = py_warnings
15191520

15201521

1521-
class EnvironmentVariableTests(BaseTest):
1522+
_NONASCII_WARNOPTION = 'ignore:DeprecationWarning' + os_helper.FS_NONASCII
1523+
1524+
1525+
class WarnOptionsTests(unittest.TestCase):
1526+
"""Tests of the -W option and the PYTHONWARNINGS environment variable.
1527+
1528+
sys.warnoptions is set by the interpreter, so these tests do not depend
1529+
on the used implementation of the warnings module.
1530+
"""
15221531

1532+
@isolation.runInSubprocess(
1533+
env={'PYTHONWARNINGS': 'ignore::DeprecationWarning',
1534+
'PYTHONDEVMODE': ''})
15231535
def test_single_warning(self):
1524-
rc, stdout, stderr = assert_python_ok("-c",
1525-
"import sys; sys.stdout.write(str(sys.warnoptions))",
1526-
PYTHONWARNINGS="ignore::DeprecationWarning",
1527-
PYTHONDEVMODE="")
1528-
self.assertEqual(stdout, b"['ignore::DeprecationWarning']")
1536+
self.assertEqual(sys.warnoptions, ['ignore::DeprecationWarning'])
15291537

1538+
@isolation.runInSubprocess(
1539+
env={'PYTHONWARNINGS': 'ignore::DeprecationWarning,'
1540+
'ignore::UnicodeWarning',
1541+
'PYTHONDEVMODE': ''})
15301542
def test_comma_separated_warnings(self):
1531-
rc, stdout, stderr = assert_python_ok("-c",
1532-
"import sys; sys.stdout.write(str(sys.warnoptions))",
1533-
PYTHONWARNINGS="ignore::DeprecationWarning,ignore::UnicodeWarning",
1534-
PYTHONDEVMODE="")
1535-
self.assertEqual(stdout,
1536-
b"['ignore::DeprecationWarning', 'ignore::UnicodeWarning']")
1543+
self.assertEqual(sys.warnoptions, ['ignore::DeprecationWarning',
1544+
'ignore::UnicodeWarning'])
15371545

1538-
@force_not_colorized
1546+
@isolation.runInSubprocess(
1547+
options=['-Wignore::UnicodeWarning'],
1548+
env={'PYTHONWARNINGS': 'ignore::DeprecationWarning',
1549+
'PYTHONDEVMODE': ''})
15391550
def test_envvar_and_command_line(self):
1540-
rc, stdout, stderr = assert_python_ok("-Wignore::UnicodeWarning", "-c",
1541-
"import sys; sys.stdout.write(str(sys.warnoptions))",
1542-
PYTHONWARNINGS="ignore::DeprecationWarning",
1543-
PYTHONDEVMODE="")
1544-
self.assertEqual(stdout,
1545-
b"['ignore::DeprecationWarning', 'ignore::UnicodeWarning']")
1551+
self.assertEqual(sys.warnoptions, ['ignore::DeprecationWarning',
1552+
'ignore::UnicodeWarning'])
1553+
1554+
@unittest.skipUnless(sys.getfilesystemencoding() != 'ascii',
1555+
'requires non-ascii filesystemencoding')
1556+
@isolation.runInSubprocess(
1557+
env={'PYTHONWARNINGS': _NONASCII_WARNOPTION,
1558+
'PYTHONDEVMODE': ''})
1559+
def test_nonascii(self):
1560+
self.assertEqual(sys.warnoptions, [_NONASCII_WARNOPTION])
1561+
1562+
1563+
class EnvironmentVariableTests(BaseTest):
1564+
1565+
def prepare_code(self, code):
1566+
"""Make the subprocess use the tested implementation."""
1567+
if self.module is py_warnings:
1568+
# Disable the warnings acceleration module in the subprocess.
1569+
code = ("import sys; sys.modules.pop('warnings', None); "
1570+
"sys.modules['_warnings'] = None; ") + code
1571+
return code
15461572

15471573
@force_not_colorized
15481574
def test_conflicting_envvar_and_command_line(self):
1549-
rc, stdout, stderr = assert_python_failure("-Werror::DeprecationWarning", "-c",
1575+
code = self.prepare_code(
15501576
"import sys, warnings; sys.stdout.write(str(sys.warnoptions)); "
1551-
"warnings.warn('Message', DeprecationWarning)",
1577+
"warnings.warn('Message', DeprecationWarning)")
1578+
rc, stdout, stderr = assert_python_failure(
1579+
"-Werror::DeprecationWarning", "-c", code,
15521580
PYTHONWARNINGS="default::DeprecationWarning",
15531581
PYTHONDEVMODE="")
15541582
self.assertEqual(stdout,
15551583
b"['default::DeprecationWarning', 'error::DeprecationWarning']")
1556-
self.assertEqual(stderr.splitlines(),
1557-
[b"Traceback (most recent call last):",
1558-
b" File \"<string>\", line 1, in <module>",
1559-
b' import sys, warnings; sys.stdout.write(str(sys.warnoptions)); warnings.w'
1560-
b"arn('Message', DeprecationWarning)",
1561-
b' ~~~~~~~~~~'
1562-
b'~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^',
1563-
b"DeprecationWarning: Message"])
1584+
# The traceback of the Python implementation contains additional
1585+
# frames, so only the ends of the traceback are checked.
1586+
lines = stderr.splitlines()
1587+
self.assertEqual(lines[0], b"Traceback (most recent call last):")
1588+
self.assertEqual(lines[1], b' File "<string>", line 1, in <module>')
1589+
self.assertEqual(lines[-1], b"DeprecationWarning: Message")
15641590

15651591
def test_default_filter_configuration(self):
15661592
pure_python_api = self.module is py_warnings
@@ -1580,30 +1606,15 @@ def test_default_filter_configuration(self):
15801606
]
15811607
expected_output = [str(f).encode() for f in expected_default_filters]
15821608

1583-
if pure_python_api:
1584-
# Disable the warnings acceleration module in the subprocess
1585-
code = "import sys; sys.modules.pop('warnings', None); sys.modules['_warnings'] = None; "
1586-
else:
1587-
code = ""
1588-
code += "import warnings; [print(f) for f in warnings._get_filters()]"
1609+
code = self.prepare_code(
1610+
"import warnings; [print(f) for f in warnings._get_filters()]")
15891611

15901612
rc, stdout, stderr = assert_python_ok("-c", code, __isolated=True)
15911613
stdout_lines = [line.strip() for line in stdout.splitlines()]
15921614
self.maxDiff = None
15931615
self.assertEqual(stdout_lines, expected_output)
15941616

15951617

1596-
@unittest.skipUnless(sys.getfilesystemencoding() != 'ascii',
1597-
'requires non-ascii filesystemencoding')
1598-
def test_nonascii(self):
1599-
PYTHONWARNINGS="ignore:DeprecationWarning" + os_helper.FS_NONASCII
1600-
rc, stdout, stderr = assert_python_ok("-c",
1601-
"import sys; sys.stdout.write(str(sys.warnoptions))",
1602-
PYTHONIOENCODING="utf-8",
1603-
PYTHONWARNINGS=PYTHONWARNINGS,
1604-
PYTHONDEVMODE="")
1605-
self.assertEqual(stdout, str([PYTHONWARNINGS]).encode())
1606-
16071618
class CEnvironmentVariableTests(EnvironmentVariableTests, unittest.TestCase):
16081619
module = c_warnings
16091620

0 commit comments

Comments
 (0)