diff options
author | Antoine Pitrou <solipsis@pitrou.net> | 2014-09-18 00:40:46 (GMT) |
---|---|---|
committer | Antoine Pitrou <solipsis@pitrou.net> | 2014-09-18 00:40:46 (GMT) |
commit | cb0a006fd11c06178a656cfdc6390b197b22fc67 (patch) | |
tree | 5d80fc387c5c75a3eb6ce80c0359e64d763aea2f /Lib | |
parent | 1b38bc65ddc337101cf0b1b02c67a9a6742b0438 (diff) | |
download | cpython-cb0a006fd11c06178a656cfdc6390b197b22fc67.zip cpython-cb0a006fd11c06178a656cfdc6390b197b22fc67.tar.gz cpython-cb0a006fd11c06178a656cfdc6390b197b22fc67.tar.bz2 |
Issue #4180: The warnings registries are now reset when the filters are modified.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/test/test_warnings.py | 49 | ||||
-rw-r--r-- | Lib/warnings.py | 17 |
2 files changed, 63 insertions, 3 deletions
diff --git a/Lib/test/test_warnings.py b/Lib/test/test_warnings.py index 43b3b9c..0f2e089 100644 --- a/Lib/test/test_warnings.py +++ b/Lib/test/test_warnings.py @@ -92,6 +92,16 @@ class FilterTests(BaseTest): self.assertRaises(UserWarning, self.module.warn, "FilterTests.test_error") + def test_error_after_default(self): + with original_warnings.catch_warnings(module=self.module) as w: + self.module.resetwarnings() + message = "FilterTests.test_ignore_after_default" + def f(): + self.module.warn(message, UserWarning) + f() + self.module.filterwarnings("error", category=UserWarning) + self.assertRaises(UserWarning, f) + def test_ignore(self): with original_warnings.catch_warnings(record=True, module=self.module) as w: @@ -100,6 +110,19 @@ class FilterTests(BaseTest): self.module.warn("FilterTests.test_ignore", UserWarning) self.assertEqual(len(w), 0) + def test_ignore_after_default(self): + with original_warnings.catch_warnings(record=True, + module=self.module) as w: + self.module.resetwarnings() + message = "FilterTests.test_ignore_after_default" + def f(): + self.module.warn(message, UserWarning) + f() + self.module.filterwarnings("ignore", category=UserWarning) + f() + f() + self.assertEqual(len(w), 1) + def test_always(self): with original_warnings.catch_warnings(record=True, module=self.module) as w: @@ -111,6 +134,26 @@ class FilterTests(BaseTest): self.module.warn(message, UserWarning) self.assertTrue(w[-1].message, 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_default(self): with original_warnings.catch_warnings(record=True, module=self.module) as w: @@ -506,7 +549,9 @@ class _WarningsTests(BaseTest, unittest.TestCase): registry=registry) self.assertEqual(w[-1].message, message) self.assertEqual(len(w), 1) - self.assertEqual(len(registry), 1) + # One actual registry key plus the "version" key + self.assertEqual(len(registry), 2) + self.assertIn("version", registry) del w[:] # Test removal. del self.module.defaultaction @@ -516,7 +561,7 @@ class _WarningsTests(BaseTest, unittest.TestCase): registry=registry) self.assertEqual(w[-1].message, message) self.assertEqual(len(w), 1) - self.assertEqual(len(registry), 1) + self.assertEqual(len(registry), 2) del w[:] # Test setting. self.module.defaultaction = "ignore" diff --git a/Lib/warnings.py b/Lib/warnings.py index eeeba65..5d5c9a9 100644 --- a/Lib/warnings.py +++ b/Lib/warnings.py @@ -53,6 +53,7 @@ def filterwarnings(action, message="", category=Warning, module="", lineno=0, filters.append(item) else: filters.insert(0, item) + _filters_mutated() def simplefilter(action, category=Warning, lineno=0, append=False): """Insert a simple entry into the list of warnings filters (at the front). @@ -73,10 +74,12 @@ def simplefilter(action, category=Warning, lineno=0, append=False): filters.append(item) else: filters.insert(0, item) + _filters_mutated() def resetwarnings(): """Clear the list of warning filters, so that no filters are active.""" filters[:] = [] + _filters_mutated() class _OptionError(Exception): """Exception used by option processing helpers.""" @@ -204,6 +207,9 @@ def warn_explicit(message, category, filename, lineno, module = module[:-3] # XXX What about leading pathname? if registry is None: registry = {} + if registry.get('version', 0) != _filters_version: + registry.clear() + registry['version'] = _filters_version if isinstance(message, Warning): text = str(message) category = message.__class__ @@ -329,6 +335,7 @@ class catch_warnings(object): self._entered = True self._filters = self._module.filters self._module.filters = self._filters[:] + self._module._filters_mutated() self._showwarning = self._module.showwarning if self._record: log = [] @@ -343,6 +350,7 @@ class catch_warnings(object): if not self._entered: raise RuntimeError("Cannot exit %r without entering first" % self) self._module.filters = self._filters + self._module._filters_mutated() self._module.showwarning = self._showwarning @@ -357,15 +365,22 @@ class catch_warnings(object): _warnings_defaults = False try: from _warnings import (filters, _defaultaction, _onceregistry, - warn, warn_explicit) + warn, warn_explicit, _filters_mutated) defaultaction = _defaultaction onceregistry = _onceregistry _warnings_defaults = True + except ImportError: filters = [] defaultaction = "default" onceregistry = {} + _filters_version = 1 + + def _filters_mutated(): + global _filters_version + _filters_version += 1 + # Module initialization _processoptions(sys.warnoptions) |