diff options
author | Martin Panter <vadmium+py@gmail.com> | 2016-05-26 09:39:41 (GMT) |
---|---|---|
committer | Martin Panter <vadmium+py@gmail.com> | 2016-05-26 09:39:41 (GMT) |
commit | b6ae2ae47ca754aed313e84990f220777cf45905 (patch) | |
tree | 39a3d3e4e0bc7765bb1e50ea83b84316d31d4d7e | |
parent | f157982b2c66be30d94a3f3ce0dfc2d9ebd3bd19 (diff) | |
parent | 43593a1892b73754e509713799a043ac756ae1e1 (diff) | |
download | cpython-b6ae2ae47ca754aed313e84990f220777cf45905.zip cpython-b6ae2ae47ca754aed313e84990f220777cf45905.tar.gz cpython-b6ae2ae47ca754aed313e84990f220777cf45905.tar.bz2 |
Issue #18383: Merge warnings fix from 3.5
-rw-r--r-- | Lib/test/test_warnings/__init__.py | 47 | ||||
-rw-r--r-- | Lib/warnings.py | 26 | ||||
-rw-r--r-- | Misc/NEWS | 3 |
3 files changed, 65 insertions, 11 deletions
diff --git a/Lib/test/test_warnings/__init__.py b/Lib/test/test_warnings/__init__.py index 42c7603..3c52b29 100644 --- a/Lib/test/test_warnings/__init__.py +++ b/Lib/test/test_warnings/__init__.py @@ -267,6 +267,53 @@ class FilterTests(BaseTest): self.module.warn_explicit(UserWarning("b"), None, "f.py", 42) 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): module = c_warnings diff --git a/Lib/warnings.py b/Lib/warnings.py index f4c8cdc..2b407ff 100644 --- a/Lib/warnings.py +++ b/Lib/warnings.py @@ -129,13 +129,8 @@ def filterwarnings(action, message="", category=Warning, module="", lineno=0, assert isinstance(module, str), "module must be a string" assert isinstance(lineno, int) and lineno >= 0, \ "lineno must be an int >= 0" - item = (action, re.compile(message, re.I), category, - re.compile(module), lineno) - if append: - filters.append(item) - else: - filters.insert(0, item) - _filters_mutated() + _add_filter(action, re.compile(message, re.I), category, + re.compile(module), lineno, append=append) def simplefilter(action, category=Warning, lineno=0, append=False): """Insert a simple entry into the list of warnings filters (at the front). @@ -151,11 +146,20 @@ def simplefilter(action, category=Warning, lineno=0, append=False): "once"), "invalid action: %r" % (action,) assert isinstance(lineno, int) and lineno >= 0, \ "lineno must be an int >= 0" - item = (action, None, category, None, lineno) - if append: - filters.append(item) - else: + _add_filter(action, None, category, None, lineno, append=append) + +def _add_filter(*item, append): + # 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) + else: + if item not in filters: + filters.append(item) _filters_mutated() def resetwarnings(): @@ -22,6 +22,9 @@ Core and Builtins Library ------- +- Issue #18383: Avoid creating duplicate filters when using filterwarnings + and simplefilter. Based on patch by Alex Shkop. + - Issue #23026: winreg.QueryValueEx() now return an integer for REG_QWORD type. - Issue #26741: subprocess.Popen destructor now emits a ResourceWarning warning |