diff --git a/Lib/test/test_warnings.py b/Lib/test/test_warnings.py --- a/Lib/test/test_warnings.py +++ b/Lib/test/test_warnings.py @@ -180,16 +180,32 @@ class FilterTests(BaseTest): self.module.resetwarnings() self.module.filterwarnings("error", "hex*", Warning, "", 0) self.assertRaises(UserWarning, self.module.warn, 'hex/oct') text = 'nonmatching text' self.module.warn(text) self.assertEqual(str(w[-1].message), text) self.assertTrue(w[-1].category is UserWarning) + def test_filterwarnings_invalid_category(self): + class MyWarningClass(Warning): + pass + + class NonWarningSubclass: + pass + + msg_regex = 'category must be a Warning subclass, not (.*)' + + with self.assertRaisesRegex(TypeError, msg_regex): + self.module.filterwarnings("always", category=MyWarningClass()) + + with self.assertRaisesRegex(TypeError, msg_regex): + self.module.filterwarnings("always", category=NonWarningSubclass) + + class CFilterTests(FilterTests, unittest.TestCase): module = c_warnings class PyFilterTests(FilterTests, unittest.TestCase): module = py_warnings class WarnTests(BaseTest): diff --git a/Lib/warnings.py b/Lib/warnings.py --- a/Lib/warnings.py +++ b/Lib/warnings.py @@ -36,21 +36,22 @@ def filterwarnings(action, message="", c '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 """ import re assert action in ("error", "ignore", "always", "default", "module", "once"), "invalid action: %r" % (action,) assert isinstance(message, str), "message must be a string" - assert isinstance(category, type), "category must be a class" - assert issubclass(category, Warning), "category must be a Warning subclass" assert isinstance(module, str), "module must be a string" assert isinstance(lineno, int) and lineno >= 0, \ "lineno must be an int >= 0" + if not (isinstance(category, type) and issubclass(category, Warning)): + raise TypeError('category must be a Warning subclass, ' + 'not {!r}'.format(category)) item = (action, re.compile(message, re.I), category, re.compile(module), lineno) if append: filters.append(item) else: filters.insert(0, item) def simplefilter(action, category=Warning, lineno=0, append=False):