[go: nahoru, domu]

Skip to content

Commit

Permalink
gh-121163: Add "all" as an valid alias for "always" in warnings.simpl…
Browse files Browse the repository at this point in the history
…efilter() (#121164)

Add support for ``all`` as an valid alias for ``always`` in ``warnings.simplefilter()``
and ``warnings.filterswarnings()``.
  • Loading branch information
Eclips4 committed Jun 30, 2024
1 parent 2a455bb commit 1a84bdc
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 43 deletions.
2 changes: 2 additions & 0 deletions Doc/library/warnings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ the disposition of the match. Each entry is a tuple of the form (*action*,
+---------------+----------------------------------------------+
| ``"always"`` | always print matching warnings |
+---------------+----------------------------------------------+
| ``"all"`` | alias to "always" |
+---------------+----------------------------------------------+
| ``"module"`` | print the first occurrence of matching |
| | warnings for each module where the warning |
| | is issued (regardless of line number) |
Expand Down
68 changes: 35 additions & 33 deletions Lib/test/test_warnings/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,40 +155,42 @@ def f():
f()
self.assertEqual(len(w), 1)

def test_always(self):
with original_warnings.catch_warnings(record=True,
module=self.module) as w:
self.module.resetwarnings()
self.module.filterwarnings("always", category=UserWarning)
message = "FilterTests.test_always"
def f():
self.module.warn(message, UserWarning)
f()
self.assertEqual(len(w), 1)
self.assertEqual(w[-1].message.args[0], message)
f()
self.assertEqual(len(w), 2)
self.assertEqual(w[-1].message.args[0], message)
def test_always_and_all(self):
for mode in {"always", "all"}:
with original_warnings.catch_warnings(record=True,
module=self.module) as w:
self.module.resetwarnings()
self.module.filterwarnings(mode, category=UserWarning)
message = "FilterTests.test_always_and_all"
def f():
self.module.warn(message, UserWarning)
f()
self.assertEqual(len(w), 1)
self.assertEqual(w[-1].message.args[0], message)
f()
self.assertEqual(len(w), 2)
self.assertEqual(w[-1].message.args[0], message)

def test_always_after_default(self):
with original_warnings.catch_warnings(record=True,
module=self.module) as w:
self.module.resetwarnings()
message = "FilterTests.test_always_after_ignore"
def f():
self.module.warn(message, UserWarning)
f()
self.assertEqual(len(w), 1)
self.assertEqual(w[-1].message.args[0], message)
f()
self.assertEqual(len(w), 1)
self.module.filterwarnings("always", category=UserWarning)
f()
self.assertEqual(len(w), 2)
self.assertEqual(w[-1].message.args[0], message)
f()
self.assertEqual(len(w), 3)
self.assertEqual(w[-1].message.args[0], message)
def test_always_and_all_after_default(self):
for mode in {"always", "all"}:
with original_warnings.catch_warnings(record=True,
module=self.module) as w:
self.module.resetwarnings()
message = "FilterTests.test_always_and_all_after_ignore"
def f():
self.module.warn(message, UserWarning)
f()
self.assertEqual(len(w), 1)
self.assertEqual(w[-1].message.args[0], message)
f()
self.assertEqual(len(w), 1)
self.module.filterwarnings(mode, category=UserWarning)
f()
self.assertEqual(len(w), 2)
self.assertEqual(w[-1].message.args[0], message)
f()
self.assertEqual(len(w), 3)
self.assertEqual(w[-1].message.args[0], message)

def test_default(self):
with original_warnings.catch_warnings(record=True,
Expand Down
15 changes: 7 additions & 8 deletions Lib/warnings.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,15 +132,15 @@ def filterwarnings(action, message="", category=Warning, module="", lineno=0,
append=False):
"""Insert an entry into the list of warnings filters (at the front).
'action' -- one of "error", "ignore", "always", "default", "module",
'action' -- one of "error", "ignore", "always", "all", "default", "module",
or "once"
'message' -- a regex that the warning message must match
'category' -- a class that the warning must be a subclass of
'module' -- a regex that the module name must match
'lineno' -- an integer line number, 0 matches all warnings
'append' -- if true, append to the list of filters
"""
if action not in {"error", "ignore", "always", "default", "module", "once"}:
if action not in {"error", "ignore", "always", "all", "default", "module", "once"}:
raise ValueError(f"invalid action: {action!r}")
if not isinstance(message, str):
raise TypeError("message must be a string")
Expand Down Expand Up @@ -171,13 +171,13 @@ def simplefilter(action, category=Warning, lineno=0, append=False):
"""Insert a simple entry into the list of warnings filters (at the front).
A simple filter matches all modules and messages.
'action' -- one of "error", "ignore", "always", "default", "module",
'action' -- one of "error", "ignore", "always", "all", "default", "module",
or "once"
'category' -- a class that the warning must be a subclass of
'lineno' -- an integer line number, 0 matches all warnings
'append' -- if true, append to the list of filters
"""
if action not in {"error", "ignore", "always", "default", "module", "once"}:
if action not in {"error", "ignore", "always", "all", "default", "module", "once"}:
raise ValueError(f"invalid action: {action!r}")
if not isinstance(lineno, int):
raise TypeError("lineno must be an int")
Expand Down Expand Up @@ -248,8 +248,7 @@ def _setoption(arg):
def _getaction(action):
if not action:
return "default"
if action == "all": return "always" # Alias
for a in ('default', 'always', 'ignore', 'module', 'once', 'error'):
for a in ('default', 'always', 'all', 'ignore', 'module', 'once', 'error'):
if a.startswith(action):
return a
raise _OptionError("invalid action: %r" % (action,))
Expand Down Expand Up @@ -397,7 +396,7 @@ def warn_explicit(message, category, filename, lineno,
if onceregistry.get(oncekey):
return
onceregistry[oncekey] = 1
elif action == "always":
elif action in {"always", "all"}:
pass
elif action == "module":
registry[key] = 1
Expand Down Expand Up @@ -690,7 +689,7 @@ def extract():

# filters contains a sequence of filter 5-tuples
# The components of the 5-tuple are:
# - an action: error, ignore, always, default, module, or once
# - an action: error, ignore, always, all, default, module, or once
# - a compiled regex that must match the warning message
# - a class representing the warning category
# - a compiled regex that must match the module that is being warned
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Add support for ``all`` as an valid ``action`` for :func:`warnings.simplefilter`
and :func:`warnings.filterswarnings`.

This comment has been minimized.

Copy link
@devdanzin

devdanzin Jul 7, 2024

Contributor

Typo in filterswarnings, should be filterwarnings.


4 changes: 2 additions & 2 deletions Python/_warnings.c
Original file line number Diff line number Diff line change
Expand Up @@ -704,9 +704,9 @@ warn_explicit(PyThreadState *tstate, PyObject *category, PyObject *message,
}

/* Store in the registry that we've been here, *except* when the action
is "always". */
is "always" or "all". */
rc = 0;
if (!_PyUnicode_EqualToASCIIString(action, "always")) {
if (!_PyUnicode_EqualToASCIIString(action, "always") && !_PyUnicode_EqualToASCIIString(action, "all")) {
if (registry != NULL && registry != Py_None &&
PyDict_SetItem(registry, key, Py_True) < 0)
{
Expand Down

0 comments on commit 1a84bdc

Please sign in to comment.