Skip to content

Commit fec77ed

Browse files
serhiy-storchakashihai1991
authored andcommitted
bpo-39056: Fix handling invalid warning category in the -W option. (pythonGH-17618)
No longer import the re module if it is not needed.
1 parent bacf7db commit fec77ed

File tree

3 files changed

+38
-17
lines changed

3 files changed

+38
-17
lines changed

Lib/test/test_warnings/__init__.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ def warnings_state(module):
4343
module.filters = original_filters
4444

4545

46+
class TestWarning(Warning):
47+
pass
48+
49+
4650
class BaseTest:
4751

4852
"""Basic bookkeeping required for testing."""
@@ -566,9 +570,28 @@ def test_improper_input(self):
566570
self.module._setoption, 'bogus::Warning')
567571
self.assertRaises(self.module._OptionError,
568572
self.module._setoption, 'ignore:2::4:-5')
573+
with self.assertRaises(self.module._OptionError):
574+
self.module._setoption('ignore::123')
575+
with self.assertRaises(self.module._OptionError):
576+
self.module._setoption('ignore::123abc')
577+
with self.assertRaises(self.module._OptionError):
578+
self.module._setoption('ignore::===')
579+
with self.assertRaisesRegex(self.module._OptionError, 'Wärning'):
580+
self.module._setoption('ignore::Wärning')
569581
self.module._setoption('error::Warning::0')
570582
self.assertRaises(UserWarning, self.module.warn, 'convert to error')
571583

584+
def test_import_from_module(self):
585+
with original_warnings.catch_warnings(module=self.module):
586+
self.module._setoption('ignore::Warning')
587+
with self.assertRaises(self.module._OptionError):
588+
self.module._setoption('ignore::TestWarning')
589+
with self.assertRaises(self.module._OptionError):
590+
self.module._setoption('ignore::test.test_warnings.bogus')
591+
self.module._setoption('error::test.test_warnings.TestWarning')
592+
with self.assertRaises(TestWarning):
593+
self.module.warn('test warning', TestWarning)
594+
572595

573596
class CWCmdLineTests(WCmdLineTests, unittest.TestCase):
574597
module = c_warnings

Lib/warnings.py

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,6 @@ def _processoptions(args):
211211

212212
# Helper for _processoptions()
213213
def _setoption(arg):
214-
import re
215214
parts = arg.split(':')
216215
if len(parts) > 5:
217216
raise _OptionError("too many fields (max 5): %r" % (arg,))
@@ -220,11 +219,13 @@ def _setoption(arg):
220219
action, message, category, module, lineno = [s.strip()
221220
for s in parts]
222221
action = _getaction(action)
223-
message = re.escape(message)
224222
category = _getcategory(category)
225-
module = re.escape(module)
223+
if message or module:
224+
import re
225+
if message:
226+
message = re.escape(message)
226227
if module:
227-
module = module + '$'
228+
module = re.escape(module) + r'\Z'
228229
if lineno:
229230
try:
230231
lineno = int(lineno)
@@ -248,26 +249,21 @@ def _getaction(action):
248249

249250
# Helper for _setoption()
250251
def _getcategory(category):
251-
import re
252252
if not category:
253253
return Warning
254-
if re.match("^[a-zA-Z0-9_]+$", category):
255-
try:
256-
cat = eval(category)
257-
except NameError:
258-
raise _OptionError("unknown warning category: %r" % (category,)) from None
254+
if '.' not in category:
255+
import builtins as m
256+
klass = category
259257
else:
260-
i = category.rfind(".")
261-
module = category[:i]
262-
klass = category[i+1:]
258+
module, _, klass = category.rpartition('.')
263259
try:
264260
m = __import__(module, None, None, [klass])
265261
except ImportError:
266262
raise _OptionError("invalid module name: %r" % (module,)) from None
267-
try:
268-
cat = getattr(m, klass)
269-
except AttributeError:
270-
raise _OptionError("unknown warning category: %r" % (category,)) from None
263+
try:
264+
cat = getattr(m, klass)
265+
except AttributeError:
266+
raise _OptionError("unknown warning category: %r" % (category,)) from None
271267
if not issubclass(cat, Warning):
272268
raise _OptionError("invalid warning category: %r" % (category,))
273269
return cat
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fixed handling invalid warning category in the -W option. No longer import
2+
the re module if it is not needed.

0 commit comments

Comments
 (0)