]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-91230: Concise catch_warnings with simplefilter (#91435)
authorZac Hatfield-Dodds <zac.hatfield.dodds@gmail.com>
Sun, 24 Apr 2022 00:55:22 +0000 (17:55 -0700)
committerGitHub <noreply@github.com>
Sun, 24 Apr 2022 00:55:22 +0000 (17:55 -0700)
Doc/library/warnings.rst
Doc/whatsnew/3.11.rst
Lib/test/test_warnings/__init__.py
Lib/warnings.py
Misc/NEWS.d/next/Library/2022-04-10-17-12-23.gh-issue-91230.T1d_fG.rst [new file with mode: 0644]

index 289b28229e1a00826a134c174c63403f47213bb5..f7a1f70833b7f5774c728b268058b93e75c5c8b3 100644 (file)
@@ -491,7 +491,7 @@ Available Functions
 Available Context Managers
 --------------------------
 
-.. class:: catch_warnings(*, record=False, module=None)
+.. class:: catch_warnings(*, record=False, module=None, action=None, category=Warning, lineno=0, append=False)
 
     A context manager that copies and, upon exit, restores the warnings filter
     and the :func:`showwarning` function.
@@ -507,6 +507,10 @@ Available Context Managers
     protected. This argument exists primarily for testing the :mod:`warnings`
     module itself.
 
+    If the *action* argument is not ``None``, the remaining arguments are
+    passed to :func:`simplefilter` as if it were called immediately on
+    entering the context.
+
     .. note::
 
         The :class:`catch_warnings` manager works by replacing and
@@ -514,3 +518,7 @@ Available Context Managers
         :func:`showwarning` function and internal list of filter
         specifications.  This means the context manager is modifying
         global state and therefore is not thread-safe.
+
+    .. versionchanged:: 3.11
+
+        Added the *action*, *category*, *lineno*, and *append* parameters.
index 34742515168c30621200db32955ac17ff114c8fb..43d8e6b1cbf414b56d1fabad52cd9f94363fba24 100644 (file)
@@ -529,6 +529,13 @@ venv
   Third party code that also creates new virtual environments should do the same.
   (Contributed by Miro HronĨok in :issue:`45413`.)
 
+warnings
+--------
+
+* :func:`warnings.catch_warnings` now accepts arguments for :func:`warnings.simplefilter`,
+  providing a more concise way to locally ignore warnings or convert them to errors.
+  (Contributed by Zac Hatfield-Dodds in :issue:`47074`.)
+
 zipfile
 -------
 
index f7f931130714c0aaaf7b480273806ac1243916e2..0f960b82bfaebc81fa2354ea29f0efee8fcb2ae7 100644 (file)
@@ -373,6 +373,25 @@ class FilterTests(BaseTest):
                 "appended duplicate changed order of filters"
             )
 
+    def test_catchwarnings_with_simplefilter_ignore(self):
+        with original_warnings.catch_warnings(module=self.module):
+            self.module.resetwarnings()
+            self.module.simplefilter("error")
+            with self.module.catch_warnings(
+                module=self.module, action="ignore"
+            ):
+                self.module.warn("This will be ignored")
+
+    def test_catchwarnings_with_simplefilter_error(self):
+        with original_warnings.catch_warnings(module=self.module):
+            self.module.resetwarnings()
+            with self.module.catch_warnings(
+                module=self.module, action="error", category=FutureWarning
+            ):
+                self.module.warn("Other types of warnings are not errors")
+                self.assertRaises(FutureWarning,
+                                  self.module.warn, FutureWarning("msg"))
+
 class CFilterTests(FilterTests, unittest.TestCase):
     module = c_warnings
 
index 887ca6ecd1a72bc3425df8e6c9b489b847a2e55f..7d8c4400127f7fee300a6d14641fdb808d26677a 100644 (file)
@@ -432,9 +432,13 @@ class catch_warnings(object):
     named 'warnings' and imported under that name. This argument is only useful
     when testing the warnings module itself.
 
+    If the 'action' argument is not None, the remaining arguments are passed
+    to warnings.simplefilter() as if it were called immediately on entering the
+    context.
     """
 
-    def __init__(self, *, record=False, module=None):
+    def __init__(self, *, record=False, module=None,
+                 action=None, category=Warning, lineno=0, append=False):
         """Specify whether to record warnings and if an alternative module
         should be used other than sys.modules['warnings'].
 
@@ -445,6 +449,10 @@ class catch_warnings(object):
         self._record = record
         self._module = sys.modules['warnings'] if module is None else module
         self._entered = False
+        if action is None:
+            self._filter = None
+        else:
+            self._filter = (action, category, lineno, append)
 
     def __repr__(self):
         args = []
@@ -464,6 +472,8 @@ class catch_warnings(object):
         self._module._filters_mutated()
         self._showwarning = self._module.showwarning
         self._showwarnmsg_impl = self._module._showwarnmsg_impl
+        if self._filter is not None:
+            simplefilter(*self._filter)
         if self._record:
             log = []
             self._module._showwarnmsg_impl = log.append
diff --git a/Misc/NEWS.d/next/Library/2022-04-10-17-12-23.gh-issue-91230.T1d_fG.rst b/Misc/NEWS.d/next/Library/2022-04-10-17-12-23.gh-issue-91230.T1d_fG.rst
new file mode 100644 (file)
index 0000000..1efc7af
--- /dev/null
@@ -0,0 +1,3 @@
+:func:`warnings.catch_warnings` now accepts arguments for
+:func:`warnings.simplefilter`, providing a more concise way to
+locally ignore warnings or convert them to errors.