Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions Lib/_py_warnings.py
Original file line number Diff line number Diff line change
Expand Up @@ -703,18 +703,18 @@ 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:
context.log = log = []
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:
Expand All @@ -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()


Expand Down
42 changes: 42 additions & 0 deletions Lib/test/test_warnings/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from contextlib import contextmanager
import linecache
import logging
import os
import importlib
import inspect
Expand Down Expand Up @@ -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

Expand Down
Loading