From ce340bc0be2f19a12c06adba4eeb6a35ef6243d9 Mon Sep 17 00:00:00 2001 From: mikemikimike <13286568797@163.com> Date: Sat, 29 Aug 2026 20:14:03 +0800 Subject: [PATCH 1/4] gh-156570: handle lazy warnings import in test helper --- Lib/test/support/warnings_helper.py | 2 +- Lib/test/test_warnings_helper.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 Lib/test/test_warnings_helper.py diff --git a/Lib/test/support/warnings_helper.py b/Lib/test/support/warnings_helper.py index c046f39fbff511..93b3053a010089 100644 --- a/Lib/test/support/warnings_helper.py +++ b/Lib/test/support/warnings_helper.py @@ -173,7 +173,7 @@ def _filterwarnings(filters, quiet=False): registry.clear() # Because test_warnings swap the module, we need to look up in the # sys.modules dictionary. - wmod = sys.modules['warnings'] + wmod = sys.modules.get('warnings', warnings) with wmod.catch_warnings(record=True) as w: # Set filter "always" to record all warnings. wmod.simplefilter("always") diff --git a/Lib/test/test_warnings_helper.py b/Lib/test/test_warnings_helper.py new file mode 100644 index 00000000000000..14f3cb79ef9721 --- /dev/null +++ b/Lib/test/test_warnings_helper.py @@ -0,0 +1,29 @@ +import sys +import unittest +from contextlib import contextmanager +from unittest.mock import patch + +from test.support import warnings_helper + + +class WarningsHelperTests(unittest.TestCase): + def test_check_warnings_when_module_is_not_in_sys_modules(self): + warnings_module = sys.modules.pop("warnings", None) + try: + @contextmanager + def catch_warnings(*, record): + self.assertTrue(record) + yield [] + + with patch.object( + warnings_helper.warnings, "catch_warnings", catch_warnings + ): + with warnings_helper.check_warnings(quiet=True): + pass + finally: + if warnings_module is not None: + sys.modules["warnings"] = warnings_module + + +if __name__ == "__main__": + unittest.main() From 33f43fddfcae49a880011a2e319df2e056a0206e Mon Sep 17 00:00:00 2001 From: mikemikimike <13286568797@163.com> Date: Sat, 29 Aug 2026 20:15:33 +0800 Subject: [PATCH 2/4] gh-156570: add news entry --- Misc/NEWS.d/next/Tests/20260829201500.gh-156570.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Tests/20260829201500.gh-156570.rst diff --git a/Misc/NEWS.d/next/Tests/20260829201500.gh-156570.rst b/Misc/NEWS.d/next/Tests/20260829201500.gh-156570.rst new file mode 100644 index 00000000000000..3a7cd1492a3f85 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/20260829201500.gh-156570.rst @@ -0,0 +1,2 @@ +Fix ``test.support.warnings_helper.check_warnings()`` failing with a +``KeyError`` when lazy imports have not populated ``sys.modules``. From d50c1faec77f023930aeec0d62a7bf20746aec55 Mon Sep 17 00:00:00 2001 From: mikemikimike <13286568797@163.com> Date: Sat, 29 Aug 2026 20:16:38 +0800 Subject: [PATCH 3/4] gh-156570: fix news entry name --- ...h-156570.rst => 2026-08-29-20-15-00.gh-issue-156570.codex.rst} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Misc/NEWS.d/next/Tests/{20260829201500.gh-156570.rst => 2026-08-29-20-15-00.gh-issue-156570.codex.rst} (100%) diff --git a/Misc/NEWS.d/next/Tests/20260829201500.gh-156570.rst b/Misc/NEWS.d/next/Tests/2026-08-29-20-15-00.gh-issue-156570.codex.rst similarity index 100% rename from Misc/NEWS.d/next/Tests/20260829201500.gh-156570.rst rename to Misc/NEWS.d/next/Tests/2026-08-29-20-15-00.gh-issue-156570.codex.rst From 97050d6b2b546e9b6e43a63a8b5eda77a1523361 Mon Sep 17 00:00:00 2001 From: mikemikimike <13286568797@163.com> Date: Sun, 30 Aug 2026 20:03:04 +0800 Subject: [PATCH 4/4] gh-156570: move warnings helper regression test --- Lib/test/test_support.py | 17 +++++++++++++++++ Lib/test/test_warnings_helper.py | 29 ----------------------------- 2 files changed, 17 insertions(+), 29 deletions(-) delete mode 100644 Lib/test/test_warnings_helper.py diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py index 243da190e48f5d..e65da66294eaaf 100644 --- a/Lib/test/test_support.py +++ b/Lib/test/test_support.py @@ -84,6 +84,23 @@ def test_ignored_deprecations_are_silent(self): messages = [str(w.message) for w in warning_objs] self.assertEqual(len(messages), 0, messages) + def test_check_warnings_when_module_is_not_in_sys_modules(self): + warnings_module = sys.modules.pop("warnings", None) + original_catch_warnings = warnings_helper.warnings.catch_warnings + try: + def catch_warnings(*, record): + return original_catch_warnings( + record=record, module=warnings_helper.warnings + ) + + warnings_helper.warnings.catch_warnings = catch_warnings + with warnings_helper.check_warnings(quiet=True): + pass + finally: + warnings_helper.warnings.catch_warnings = original_catch_warnings + if warnings_module is not None: + sys.modules["warnings"] = warnings_module + def test_import_module(self): import_helper.import_module("ftplib") self.assertRaises(unittest.SkipTest, diff --git a/Lib/test/test_warnings_helper.py b/Lib/test/test_warnings_helper.py deleted file mode 100644 index 14f3cb79ef9721..00000000000000 --- a/Lib/test/test_warnings_helper.py +++ /dev/null @@ -1,29 +0,0 @@ -import sys -import unittest -from contextlib import contextmanager -from unittest.mock import patch - -from test.support import warnings_helper - - -class WarningsHelperTests(unittest.TestCase): - def test_check_warnings_when_module_is_not_in_sys_modules(self): - warnings_module = sys.modules.pop("warnings", None) - try: - @contextmanager - def catch_warnings(*, record): - self.assertTrue(record) - yield [] - - with patch.object( - warnings_helper.warnings, "catch_warnings", catch_warnings - ): - with warnings_helper.check_warnings(quiet=True): - pass - finally: - if warnings_module is not None: - sys.modules["warnings"] = warnings_module - - -if __name__ == "__main__": - unittest.main()