FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

gh-134716: Support regular expressions in -W and PYTHONWARNINGS by serhiy-storchaka · Pull Request #138149 · python/cpython · GitHub

Repository navigation

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension .py  (2) .rst  (4) All 2 file types selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
10 changes: 7 additions & 3 deletions Doc/library/warnings.rst
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -159,16 +159,20 @@ the disposition of the match. Each entry is a tuple of the form (*action*,

* *message* is a string containing a regular expression that the start of
the warning message must match, case-insensitively. In :option:`-W` and
:envvar:`PYTHONWARNINGS`, *message* is a literal string that the start of the
warning message must contain (case-insensitively), ignoring any whitespace at
:envvar:`PYTHONWARNINGS`, if *message* starts and ends with a forward slash
(``/``), it specifies a regular expression as above;
otherwise it is a literal string that the start of the
warning message must match (case-insensitively), ignoring any whitespace at
the start or end of *message*.

* *category* is a class (a subclass of :exc:`Warning`) of which the warning
category must be a subclass in order to match.

* *module* is a string containing a regular expression that the start of the
fully qualified module name must match, case-sensitively. In :option:`-W` and
:envvar:`PYTHONWARNINGS`, *module* is a literal string that the
:envvar:`PYTHONWARNINGS`, if *module* starts and ends with a forward slash
(``/``), it specifies a regular expression as above;
otherwise it is a literal string that the
fully qualified module name must be equal to (case-sensitively), ignoring any
whitespace at the start or end of *module*.

Expand Down
16 changes: 14 additions & 2 deletions Doc/using/cmdline.rst
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -479,8 +479,10 @@ Miscellaneous options
The *action* field is as explained above but only applies to warnings that
match the remaining fields.

The *message* field must match the whole warning message; this match is
case-insensitive.
The *message* field must match the start of the warning message;
this match is case-insensitive.
If it starts and ends with a forward slash (``/``), it specifies
a regular expression, otherwise it specifies a literal string.

The *category* field matches the warning category
(ex: ``DeprecationWarning``). This must be a class name; the match test
Expand All @@ -489,6 +491,10 @@ Miscellaneous options

The *module* field matches the (fully qualified) module name; this match is
case-sensitive.
If it starts and ends with a forward slash (``/``), it specifies
a regular expression that the start of the fully qualified module name
must match, otherwise it specifies a literal string that the fully
qualified module name must be equal to.

The *lineno* field matches the line number, where zero matches all line
numbers and is thus equivalent to an omitted line number.
Expand All @@ -506,6 +512,9 @@ Miscellaneous options
See :ref:`warning-filter` and :ref:`describing-warning-filters` for more
details.

.. versionchanged:: next
Added regular expression support for *message* and *module*.


.. option:: -x

Expand Down Expand Up @@ -980,6 +989,9 @@ conflict.
See :ref:`warning-filter` and :ref:`describing-warning-filters` for more
details.

.. versionchanged:: next
Added regular expression support for *message* and *module*.


.. envvar:: PYTHONFAULTHANDLER

Expand Down
6 changes: 6 additions & 0 deletions Doc/whatsnew/3.15.rst
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,12 @@ Other language changes
This speeds up class creation, and helps avoid reference cycles.
(Contributed by Petr Viktorin in :gh:`135228`.)

* The :option:`-W` option and the :envvar:`PYTHONWARNINGS` environment variable
can now specify regular expressions instead of literal strings to match
the warning message and the module name, if the corresponding field starts
and ends with a forward slash (``/``).
(Contributed by Serhiy Storchaka in :gh:`134716`.)


New modules
===========
Expand Down
28 changes: 25 additions & 3 deletions Lib/_py_warnings.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -369,9 +369,15 @@ def _setoption(arg):
if message or module:
import re
if message:
message = re.escape(message)
if len(message) >= 2 and message[0] == message[-1] == '/':
message = message[1:-1]
else:
message = re.escape(message)
if module:
module = re.escape(module) + r'\z'
if len(module) >= 2 and module[0] == module[-1] == '/':
module = module[1:-1]
else:
module = re.escape(module) + r'\z'
if lineno:
try:
lineno = int(lineno)
Expand All @@ -381,7 +387,23 @@ def _setoption(arg):
raise _wm._OptionError("invalid lineno %r" % (lineno,)) from None
else:
lineno = 0
_wm.filterwarnings(action, message, category, module, lineno)
try:
_wm.filterwarnings(action, message, category, module, lineno)
except re.PatternError if message or module else ():
if message:
try:
re.compile(message)
except re.PatternError:
raise _wm._OptionError(f"invalid regular expression for "
f"message: {message!r}") from None
if module:
try:
re.compile(module)
except re.PatternError:
raise _wm._OptionError(f"invalid regular expression for "
f"module: {module!r}") from None
# Should never happen.
raise


# Helper for _setoption()
Expand Down
29 changes: 29 additions & 0 deletions Lib/test/test_warnings/__init__.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -755,6 +755,10 @@ def test_improper_input(self):
self.module._setoption('ignore::===')
with self.assertRaisesRegex(self.module._OptionError, 'Wärning'):
self.module._setoption('ignore::Wärning')
with self.assertRaisesRegex(self.module._OptionError, 'message'):
self.module._setoption('ignore:/?/:Warning')
with self.assertRaisesRegex(self.module._OptionError, 'module'):
self.module._setoption('ignore::Warning:/?/')
self.module._setoption('error::Warning::0')
self.assertRaises(UserWarning, self.module.warn, 'convert to error')

Expand All @@ -769,6 +773,31 @@ def test_import_from_module(self):
with self.assertRaises(TestWarning):
self.module.warn('test warning', TestWarning)

def test_message(self):
# Match prefix, case-insensitive.
with self.module.catch_warnings():
self.module._setoption('error:TEST WARN:UserWarning')
with self.assertRaises(UserWarning):
self.module.warn('Test Warning')
with self.module.catch_warnings():
self.module._setoption(r'error:/TE.*WARN/:UserWarning')
with self.assertRaises(UserWarning):
self.module.warn('Test Warning')

def test_module(self):
with self.module.catch_warnings():
self.module._setoption(f'error::UserWarning:{__name__}')
with self.assertRaises(UserWarning):
self.module.warn('test warning')
# Only full match.
self.module._setoption(f'ignore::UserWarning:{__name__[:-2]}')
with self.assertRaises(UserWarning):
self.module.warn('test warning')
with self.module.catch_warnings():
self.module._setoption(f'error::UserWarning:/{re.escape(__name__[:-2])}./')
with self.assertRaises(UserWarning):
self.module.warn('test warning')


class CWCmdLineTests(WCmdLineTests, unittest.TestCase):
module = c_warnings
Expand Down
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Add support of regular expressions in the :option:`-W` option and the
:envvar:`PYTHONWARNINGS` environment variable.
Loading

Back | FazBrowse Home | New Git URL