Skip to content

Commit c9b21ef

Browse files
committed
gh-146358: Fix warnings.catch_warnings on Free Threading
catch_warnings now also overrides warnings.showwarning() on Free Threading to support custom warnings.showwarning().
1 parent 68c7fad commit c9b21ef

File tree

2 files changed

+27
-5
lines changed

2 files changed

+27
-5
lines changed

Lib/_py_warnings.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -703,18 +703,18 @@ def __enter__(self):
703703
context = None
704704
self._filters = self._module.filters
705705
self._module.filters = self._filters[:]
706-
self._showwarning = self._module.showwarning
707706
self._showwarnmsg_impl = self._module._showwarnmsg_impl
707+
self._showwarning = self._module.showwarning
708708
self._module._filters_mutated_lock_held()
709709
if self._record:
710710
if _use_context:
711711
context.log = log = []
712712
else:
713713
log = []
714714
self._module._showwarnmsg_impl = log.append
715-
# Reset showwarning() to the default implementation to make sure
716-
# that _showwarnmsg() calls _showwarnmsg_impl()
717-
self._module.showwarning = self._module._showwarning_orig
715+
# Reset showwarning() to the default implementation to make sure
716+
# that _showwarnmsg() calls _showwarnmsg_impl()
717+
self._module.showwarning = self._module._showwarning_orig
718718
else:
719719
log = None
720720
if self._filter is not None:
@@ -729,8 +729,8 @@ def __exit__(self, *exc_info):
729729
self._module._warnings_context.set(self._saved_context)
730730
else:
731731
self._module.filters = self._filters
732-
self._module.showwarning = self._showwarning
733732
self._module._showwarnmsg_impl = self._showwarnmsg_impl
733+
self._module.showwarning = self._showwarning
734734
self._module._filters_mutated_lock_held()
735735

736736

Lib/test/test_warnings/__init__.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,28 @@ def test_catchwarnings_with_simplefilter_error(self):
509509
stderr = stderr.getvalue()
510510
self.assertIn(error_msg, stderr)
511511

512+
def test_catchwarnings_with_showwarning(self):
513+
# gh-146358: catch_warnings must override warnings.showwarning()
514+
# if it's not the default implementation.
515+
516+
warns = []
517+
def custom_showwarning(message, category, filename, lineno,
518+
file=None, line=None):
519+
warns.append(message)
520+
521+
with support.swap_attr(self.module, 'showwarning', custom_showwarning):
522+
with self.module.catch_warnings(record=True) as recorded:
523+
self.module.warn("recorded")
524+
self.assertEqual(len(recorded), 1)
525+
self.assertEqual(str(recorded[0].message), 'recorded')
526+
self.assertIs(self.module.showwarning, custom_showwarning)
527+
528+
self.module.warn("custom")
529+
530+
self.assertEqual(len(warns), 1)
531+
self.assertEqual(str(warns[0]), "custom")
532+
533+
512534
class CFilterTests(FilterTests, unittest.TestCase):
513535
module = c_warnings
514536

0 commit comments

Comments
 (0)