From 41ec17e45d54473d32f543396293256f1581e44d Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 5 Jan 2020 14:15:27 +0200 Subject: [PATCH] bpo-39056: Fix handling invalid warning category in the -W option. (GH-17618) No longer import the re module if it is not needed. --- Lib/test/test_warnings/__init__.py | 23 ++++++++++++++ Lib/warnings.py | 30 ++++++++----------- .../2019-12-15-21-05-16.bpo-39056.nEfUM9.rst | 2 ++ 3 files changed, 38 insertions(+), 17 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-12-15-21-05-16.bpo-39056.nEfUM9.rst diff --git a/Lib/test/test_warnings/__init__.py b/Lib/test/test_warnings/__init__.py index 3a6d64eaad1..c6fb097ae6d 100644 --- a/Lib/test/test_warnings/__init__.py +++ b/Lib/test/test_warnings/__init__.py @@ -43,6 +43,10 @@ def warnings_state(module): module.filters = original_filters +class TestWarning(Warning): + pass + + class BaseTest: """Basic bookkeeping required for testing.""" @@ -566,9 +570,28 @@ class WCmdLineTests(BaseTest): self.module._setoption, 'bogus::Warning') self.assertRaises(self.module._OptionError, self.module._setoption, 'ignore:2::4:-5') + with self.assertRaises(self.module._OptionError): + self.module._setoption('ignore::123') + with self.assertRaises(self.module._OptionError): + self.module._setoption('ignore::123abc') + with self.assertRaises(self.module._OptionError): + self.module._setoption('ignore::===') + with self.assertRaisesRegex(self.module._OptionError, 'Wärning'): + self.module._setoption('ignore::Wärning') self.module._setoption('error::Warning::0') self.assertRaises(UserWarning, self.module.warn, 'convert to error') + def test_import_from_module(self): + with original_warnings.catch_warnings(module=self.module): + self.module._setoption('ignore::Warning') + with self.assertRaises(self.module._OptionError): + self.module._setoption('ignore::TestWarning') + with self.assertRaises(self.module._OptionError): + self.module._setoption('ignore::test.test_warnings.bogus') + self.module._setoption('error::test.test_warnings.TestWarning') + with self.assertRaises(TestWarning): + self.module.warn('test warning', TestWarning) + class CWCmdLineTests(WCmdLineTests, unittest.TestCase): module = c_warnings diff --git a/Lib/warnings.py b/Lib/warnings.py index 00f740ca3a9..691ccddfa45 100644 --- a/Lib/warnings.py +++ b/Lib/warnings.py @@ -211,7 +211,6 @@ def _processoptions(args): # Helper for _processoptions() def _setoption(arg): - import re parts = arg.split(':') if len(parts) > 5: raise _OptionError("too many fields (max 5): %r" % (arg,)) @@ -220,11 +219,13 @@ def _setoption(arg): action, message, category, module, lineno = [s.strip() for s in parts] action = _getaction(action) - message = re.escape(message) category = _getcategory(category) - module = re.escape(module) + if message or module: + import re + if message: + message = re.escape(message) if module: - module = module + '$' + module = re.escape(module) + r'\Z' if lineno: try: lineno = int(lineno) @@ -248,26 +249,21 @@ def _getaction(action): # Helper for _setoption() def _getcategory(category): - import re if not category: return Warning - if re.match("^[a-zA-Z0-9_]+$", category): - try: - cat = eval(category) - except NameError: - raise _OptionError("unknown warning category: %r" % (category,)) from None + if '.' not in category: + import builtins as m + klass = category else: - i = category.rfind(".") - module = category[:i] - klass = category[i+1:] + module, _, klass = category.rpartition('.') try: m = __import__(module, None, None, [klass]) except ImportError: raise _OptionError("invalid module name: %r" % (module,)) from None - try: - cat = getattr(m, klass) - except AttributeError: - raise _OptionError("unknown warning category: %r" % (category,)) from None + try: + cat = getattr(m, klass) + except AttributeError: + raise _OptionError("unknown warning category: %r" % (category,)) from None if not issubclass(cat, Warning): raise _OptionError("invalid warning category: %r" % (category,)) return cat diff --git a/Misc/NEWS.d/next/Library/2019-12-15-21-05-16.bpo-39056.nEfUM9.rst b/Misc/NEWS.d/next/Library/2019-12-15-21-05-16.bpo-39056.nEfUM9.rst new file mode 100644 index 00000000000..d5d2b98e9b0 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-12-15-21-05-16.bpo-39056.nEfUM9.rst @@ -0,0 +1,2 @@ +Fixed handling invalid warning category in the -W option. No longer import +the re module if it is not needed.