diff --git a/Doc/library/warnings.rst b/Doc/library/warnings.rst index fe11aabbcbdd6b4..ec9afa59da24e25 100644 --- a/Doc/library/warnings.rst +++ b/Doc/library/warnings.rst @@ -199,7 +199,9 @@ precedence over earlier ones). Commonly used warning filters apply to either all warnings, warnings in a particular category, or warnings raised by particular modules or packages. -Some examples:: +Some examples: + +.. code-block:: none default # Show all warnings (even those ignored by default) ignore # Ignore all warnings @@ -207,8 +209,8 @@ Some examples:: error::ResourceWarning # Treat ResourceWarning messages as errors default::DeprecationWarning # Show DeprecationWarning messages ignore,default:::mymodule # Only report warnings triggered by "mymodule" - error:::mymodule[.*] # Convert warnings to errors in "mymodule" - # and any subpackages of "mymodule" + error:::mymodule(\..*)? # Convert warnings to errors in "mymodule" + # and any of its submodules and subpackages .. _default-warning-filter: diff --git a/Lib/test/test_warnings/__init__.py b/Lib/test/test_warnings/__init__.py index 4b1b4e193cb165b..da37a2e55eec172 100644 --- a/Lib/test/test_warnings/__init__.py +++ b/Lib/test/test_warnings/__init__.py @@ -1157,6 +1157,26 @@ def test_envvar_and_command_line(self): self.assertEqual(stdout, b"['ignore::DeprecationWarning', 'ignore::UnicodeWarning']") + def test_module_regex(self): + WARN_NOWHERE = 'True' + WARN_IN_MAIN = "import warnings; warnings.warn('__main__ warning');" + WARN_IN_SUBMOD = "import test.test_warnings.data.submodule_warning;" + # Check the warning is ignored by default: + assert_python_ok("-c", WARN_IN_MAIN, PYTHONWARNINGS="") + assert_python_ok("-c", WARN_IN_MAIN, PYTHONWARNINGS="ignore") + assert_python_ok("-c", WARN_IN_SUBMOD, PYTHONWARNINGS="") + assert_python_ok("-c", WARN_IN_SUBMOD, PYTHONWARNINGS="ignore") + # The submodule warning is still ignored because the pattern selects + # only to the package itself, not the submodule: + assert_python_ok("-c", WARN_IN_SUBMOD, PYTHONWARNINGS="error:::test") + # Warnings can be enabled by using wildcard regex: + assert_python_ok("-c", WARN_NOWHERE, PYTHONWARNINGS="error:::.*") + assert_python_failure("-c", WARN_IN_MAIN, PYTHONWARNINGS="error:::.*") + assert_python_failure("-c", WARN_IN_SUBMOD, PYTHONWARNINGS="error:::.*") + # Warning from submodule is raised using a more specific pattern: + assert_python_failure("-c", WARN_IN_SUBMOD, + PYTHONWARNINGS=r"error:::test.test_warnings(\..*)?") + def test_conflicting_envvar_and_command_line(self): rc, stdout, stderr = assert_python_failure("-Werror::DeprecationWarning", "-c", "import sys, warnings; sys.stdout.write(str(sys.warnoptions)); " diff --git a/Lib/test/test_warnings/data/submodule_warning.py b/Lib/test/test_warnings/data/submodule_warning.py new file mode 100644 index 000000000000000..2d47886a7e7e49f --- /dev/null +++ b/Lib/test/test_warnings/data/submodule_warning.py @@ -0,0 +1,3 @@ +import warnings + +warnings.warn('submodule warning', DeprecationWarning) diff --git a/Lib/warnings.py b/Lib/warnings.py index 691ccddfa450ad2..c33b008ebb8a490 100644 --- a/Lib/warnings.py +++ b/Lib/warnings.py @@ -220,12 +220,8 @@ def _setoption(arg): for s in parts] action = _getaction(action) category = _getcategory(category) - if message or module: - import re - if message: - message = re.escape(message) if module: - module = re.escape(module) + r'\Z' + module = r'\A(' + module + r')\Z' if lineno: try: lineno = int(lineno) diff --git a/Misc/NEWS.d/next/Library/2018-09-30-19-49-37.bpo-34624.UrjcKN.rst b/Misc/NEWS.d/next/Library/2018-09-30-19-49-37.bpo-34624.UrjcKN.rst new file mode 100644 index 000000000000000..feb7f97e18564ab --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-09-30-19-49-37.bpo-34624.UrjcKN.rst @@ -0,0 +1,2 @@ +When passing warning filters via ``-W`` or ``PYTHONWARNINGS``, treat the +``module`` part as regex.