https://github.com/python/cpython/commit/0055140b2cf3e3a86ef9ab7a39e2083212b27c58
commit: 0055140b2cf3e3a86ef9ab7a39e2083212b27c58
branch: main
author: Victor Stinner <[email protected]>
committer: vstinner <[email protected]>
date: 2026-03-25T14:34:50+01:00
summary:
gh-146358: Fix warnings.catch_warnings on Free Threading (#146374)
catch_warnings now also overrides warnings.showwarning() on Free
Threading to support custom warnings.showwarning().
files:
M Lib/_py_warnings.py
M Lib/test/test_warnings/__init__.py
diff --git a/Lib/_py_warnings.py b/Lib/_py_warnings.py
index d5a9cec86f3674..81a386c4487d95 100644
--- a/Lib/_py_warnings.py
+++ b/Lib/_py_warnings.py
@@ -703,8 +703,8 @@ def __enter__(self):
context = None
self._filters = self._module.filters
self._module.filters = self._filters[:]
- self._showwarning = self._module.showwarning
self._showwarnmsg_impl = self._module._showwarnmsg_impl
+ self._showwarning = self._module.showwarning
self._module._filters_mutated_lock_held()
if self._record:
if _use_context:
@@ -712,9 +712,9 @@ def __enter__(self):
else:
log = []
self._module._showwarnmsg_impl = log.append
- # Reset showwarning() to the default implementation to
make sure
- # that _showwarnmsg() calls _showwarnmsg_impl()
- self._module.showwarning = self._module._showwarning_orig
+ # Reset showwarning() to the default implementation to make
sure
+ # that _showwarnmsg() calls _showwarnmsg_impl()
+ self._module.showwarning = self._module._showwarning_orig
else:
log = None
if self._filter is not None:
@@ -729,8 +729,8 @@ def __exit__(self, *exc_info):
self._module._warnings_context.set(self._saved_context)
else:
self._module.filters = self._filters
- self._module.showwarning = self._showwarning
self._module._showwarnmsg_impl = self._showwarnmsg_impl
+ self._module.showwarning = self._showwarning
self._module._filters_mutated_lock_held()
diff --git a/Lib/test/test_warnings/__init__.py
b/Lib/test/test_warnings/__init__.py
index a6af5057cc8968..d86844c1a29a9a 100644
--- a/Lib/test/test_warnings/__init__.py
+++ b/Lib/test/test_warnings/__init__.py
@@ -1,5 +1,6 @@
from contextlib import contextmanager
import linecache
+import logging
import os
import importlib
import inspect
@@ -509,6 +510,47 @@ def test_catchwarnings_with_simplefilter_error(self):
stderr = stderr.getvalue()
self.assertIn(error_msg, stderr)
+ def test_catchwarnings_with_showwarning(self):
+ # gh-146358: catch_warnings must override warnings.showwarning()
+ # if it's not the default implementation.
+
+ warns = []
+ def custom_showwarning(message, category, filename, lineno,
+ file=None, line=None):
+ warns.append(message)
+
+ with self.module.catch_warnings():
+ self.module.resetwarnings()
+
+ with support.swap_attr(self.module, 'showwarning',
+ custom_showwarning):
+ with self.module.catch_warnings(record=True) as recorded:
+ self.module.warn("recorded")
+ self.assertEqual(len(recorded), 1)
+ self.assertEqual(str(recorded[0].message), 'recorded')
+ self.assertIs(self.module.showwarning, custom_showwarning)
+
+ self.module.warn("custom")
+
+ self.assertEqual(len(warns), 1)
+ self.assertEqual(str(warns[0]), "custom")
+
+ def test_catchwarnings_logging(self):
+ # gh-146358: catch_warnings(record=True) must replace the
+ # showwarning() function set by logging.captureWarnings(True).
+
+ with self.module.catch_warnings():
+ self.module.resetwarnings()
+ logging.captureWarnings(True)
+
+ with self.module.catch_warnings(record=True) as recorded:
+ self.module.warn("recorded")
+ self.assertEqual(len(recorded), 1)
+ self.assertEqual(str(recorded[0].message), 'recorded')
+
+ logging.captureWarnings(False)
+
+
class CFilterTests(FilterTests, 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]