bpo-39056: Fix handling invalid warning category in the -W option. (GH-17618)

No longer import the re module if it is not needed.
This commit is contained in:
Serhiy Storchaka 2020-01-05 14:15:27 +02:00 committed by GitHub
parent 6a265f0d0c
commit 41ec17e45d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 38 additions and 17 deletions

View File

@ -43,6 +43,10 @@ def warnings_state(module):
module.filters = original_filters module.filters = original_filters
class TestWarning(Warning):
pass
class BaseTest: class BaseTest:
"""Basic bookkeeping required for testing.""" """Basic bookkeeping required for testing."""
@ -566,9 +570,28 @@ class WCmdLineTests(BaseTest):
self.module._setoption, 'bogus::Warning') self.module._setoption, 'bogus::Warning')
self.assertRaises(self.module._OptionError, self.assertRaises(self.module._OptionError,
self.module._setoption, 'ignore:2::4:-5') 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.module._setoption('error::Warning::0')
self.assertRaises(UserWarning, self.module.warn, 'convert to error') 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): class CWCmdLineTests(WCmdLineTests, unittest.TestCase):
module = c_warnings module = c_warnings

View File

@ -211,7 +211,6 @@ def _processoptions(args):
# Helper for _processoptions() # Helper for _processoptions()
def _setoption(arg): def _setoption(arg):
import re
parts = arg.split(':') parts = arg.split(':')
if len(parts) > 5: if len(parts) > 5:
raise _OptionError("too many fields (max 5): %r" % (arg,)) raise _OptionError("too many fields (max 5): %r" % (arg,))
@ -220,11 +219,13 @@ def _setoption(arg):
action, message, category, module, lineno = [s.strip() action, message, category, module, lineno = [s.strip()
for s in parts] for s in parts]
action = _getaction(action) action = _getaction(action)
message = re.escape(message)
category = _getcategory(category) category = _getcategory(category)
module = re.escape(module) if message or module:
import re
if message:
message = re.escape(message)
if module: if module:
module = module + '$' module = re.escape(module) + r'\Z'
if lineno: if lineno:
try: try:
lineno = int(lineno) lineno = int(lineno)
@ -248,18 +249,13 @@ def _getaction(action):
# Helper for _setoption() # Helper for _setoption()
def _getcategory(category): def _getcategory(category):
import re
if not category: if not category:
return Warning return Warning
if re.match("^[a-zA-Z0-9_]+$", category): if '.' not in category:
try: import builtins as m
cat = eval(category) klass = category
except NameError:
raise _OptionError("unknown warning category: %r" % (category,)) from None
else: else:
i = category.rfind(".") module, _, klass = category.rpartition('.')
module = category[:i]
klass = category[i+1:]
try: try:
m = __import__(module, None, None, [klass]) m = __import__(module, None, None, [klass])
except ImportError: except ImportError:

View File

@ -0,0 +1,2 @@
Fixed handling invalid warning category in the -W option. No longer import
the re module if it is not needed.