Commit f6ffab72 authored by Martin Panter's avatar Martin Panter

Issue #18383: Avoid adding duplicate filters when warnings is reloaded

Based on patch by Alex Shkop.
parent 1ce57163
...@@ -265,6 +265,53 @@ class FilterTests(BaseTest): ...@@ -265,6 +265,53 @@ class FilterTests(BaseTest):
self.module.warn_explicit(UserWarning("b"), None, "f.py", 42) self.module.warn_explicit(UserWarning("b"), None, "f.py", 42)
self.assertEqual(str(w[-1].message), "b") self.assertEqual(str(w[-1].message), "b")
def test_filterwarnings_duplicate_filters(self):
with original_warnings.catch_warnings(module=self.module):
self.module.resetwarnings()
self.module.filterwarnings("error", category=UserWarning)
self.assertEqual(len(self.module.filters), 1)
self.module.filterwarnings("ignore", category=UserWarning)
self.module.filterwarnings("error", category=UserWarning)
self.assertEqual(
len(self.module.filters), 2,
"filterwarnings inserted duplicate filter"
)
self.assertEqual(
self.module.filters[0][0], "error",
"filterwarnings did not promote filter to "
"the beginning of list"
)
def test_simplefilter_duplicate_filters(self):
with original_warnings.catch_warnings(module=self.module):
self.module.resetwarnings()
self.module.simplefilter("error", category=UserWarning)
self.assertEqual(len(self.module.filters), 1)
self.module.simplefilter("ignore", category=UserWarning)
self.module.simplefilter("error", category=UserWarning)
self.assertEqual(
len(self.module.filters), 2,
"simplefilter inserted duplicate filter"
)
self.assertEqual(
self.module.filters[0][0], "error",
"simplefilter did not promote filter to the beginning of list"
)
def test_append_duplicate(self):
with original_warnings.catch_warnings(module=self.module,
record=True) as w:
self.module.resetwarnings()
self.module.simplefilter("ignore")
self.module.simplefilter("error", append=True)
self.module.simplefilter("ignore", append=True)
self.module.warn("test_append_duplicate", category=UserWarning)
self.assertEqual(len(self.module.filters), 2,
"simplefilter inserted duplicate filter"
)
self.assertEqual(len(w), 0,
"appended duplicate changed order of filters"
)
class CFilterTests(FilterTests, unittest.TestCase): class CFilterTests(FilterTests, unittest.TestCase):
module = c_warnings module = c_warnings
......
...@@ -56,13 +56,8 @@ def filterwarnings(action, message="", category=Warning, module="", lineno=0, ...@@ -56,13 +56,8 @@ def filterwarnings(action, message="", category=Warning, module="", lineno=0,
assert isinstance(module, str), "module must be a string" assert isinstance(module, str), "module must be a string"
assert isinstance(lineno, int) and lineno >= 0, \ assert isinstance(lineno, int) and lineno >= 0, \
"lineno must be an int >= 0" "lineno must be an int >= 0"
item = (action, re.compile(message, re.I), category, _add_filter(action, re.compile(message, re.I), category,
re.compile(module), lineno) re.compile(module), lineno, append=append)
if append:
filters.append(item)
else:
filters.insert(0, item)
_filters_mutated()
def simplefilter(action, category=Warning, lineno=0, append=False): def simplefilter(action, category=Warning, lineno=0, append=False):
"""Insert a simple entry into the list of warnings filters (at the front). """Insert a simple entry into the list of warnings filters (at the front).
...@@ -78,11 +73,20 @@ def simplefilter(action, category=Warning, lineno=0, append=False): ...@@ -78,11 +73,20 @@ def simplefilter(action, category=Warning, lineno=0, append=False):
"once"), "invalid action: %r" % (action,) "once"), "invalid action: %r" % (action,)
assert isinstance(lineno, int) and lineno >= 0, \ assert isinstance(lineno, int) and lineno >= 0, \
"lineno must be an int >= 0" "lineno must be an int >= 0"
item = (action, None, category, None, lineno) _add_filter(action, None, category, None, lineno, append=append)
if append:
filters.append(item) def _add_filter(*item, append):
else: # Remove possible duplicate filters, so new one will be placed
# in correct place. If append=True and duplicate exists, do nothing.
if not append:
try:
filters.remove(item)
except ValueError:
pass
filters.insert(0, item) filters.insert(0, item)
else:
if item not in filters:
filters.append(item)
_filters_mutated() _filters_mutated()
def resetwarnings(): def resetwarnings():
......
...@@ -126,6 +126,9 @@ Core and Builtins ...@@ -126,6 +126,9 @@ Core and Builtins
Library Library
------- -------
- Issue #18383: Avoid creating duplicate filters when using filterwarnings
and simplefilter. Based on patch by Alex Shkop.
- Issue #27057: Fix os.set_inheritable() on Android, ioctl() is blocked by - Issue #27057: Fix os.set_inheritable() on Android, ioctl() is blocked by
SELinux and fails with EACCESS. The function now falls back to fcntl(). SELinux and fails with EACCESS. The function now falls back to fcntl().
Patch written by Michał Bednarski. Patch written by Michał Bednarski.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment