summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2020-01-05 04:34:58 -0800
committerGitHub <noreply@github.com>2020-01-05 04:34:58 -0800
commit43fbc70360b2a934ea809b2175d7e99031db2df3 (patch)
treeb3d5638512d964a1dbcb6149449b1cadf1dd58e3
parent3bdb2d9daf3ce41b325bd508e3dd29041e85dd1f (diff)
downloadcpython-git-43fbc70360b2a934ea809b2175d7e99031db2df3.tar.gz
bpo-39056: Fix handling invalid warning category in the -W option. (GH-17618)
No longer import the re module if it is not needed. (cherry picked from commit 41ec17e45d54473d32f543396293256f1581e44d) Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
-rw-r--r--Lib/test/test_warnings/__init__.py23
-rw-r--r--Lib/warnings.py30
-rw-r--r--Misc/NEWS.d/next/Library/2019-12-15-21-05-16.bpo-39056.nEfUM9.rst2
3 files changed, 38 insertions, 17 deletions
diff --git a/Lib/test/test_warnings/__init__.py b/Lib/test/test_warnings/__init__.py
index 87cc3a7e36..d41f3dff02 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."""
@@ -629,9 +633,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 9064f56827..3e1715c4b4 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 0000000000..d5d2b98e9b
--- /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.