'Why does Python's filterwarning module regex not work as expected?

According to the Python warnings documentation the filterwarnings pattern is action:message:category:module:line, and the module part should allow for matching specific modules against a regex. I'm trying to make this work to filter specific warnings for third party library modules, but the feature doesn't seem to work.

Minimal example

A simpler way to reproduce the issue is to create a file

my_module.py

print("\d")

and then run PYTHONWARNINGS="error,ignore:::.*" python -c "import my_module" from the same directory. Clearly the regex .* should match the module name my_module, but somehow it doesn't. The question is why?

Original example

As an example: Importing rosbag package (some package that comes with the Robot Operating System (ROS) distribution) triggers an error when running in "strict" report-warnings-as-errors mode:

$ PYTHONWARNINGS='error' python -c "import rosbag"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/<PATH-TO-ROS-DISTRIBUTION>/lib/python3/dist-packages/rosbag/__init__.py", line 33, in <module>
    from .bag import Bag, Compression, ROSBagException, ROSBagFormatException, ROSBagUnindexedException
  File "/<PATH-TO-ROS-DISTRIBUTION>/lib/python3/dist-packages/rosbag/bag.py", line 1568
    matches = re.match("#ROS(.*) V(\d).(\d)", version_line)
                       ^
SyntaxError: invalid escape sequence \d

That makes sense, it should use a raw string literal.

Now I'm trying to use a module regex to silence the warning from the rosbag module. For the purpose of the example I'm specifying the filterwarnings via PYTHONWARNINGS but other methods like via pytests settings result in the same behavior.

I'm getting the following unexpected behavior:

  • using PYTHONWARNINGS='error,ignore:invalid escape sequence::' works. Of course that filters all "invalid escape sequence" warnings. So let's add a module regex at the end to be module specific...
  • using PYTHONWARNINGS='error,ignore:invalid escape sequence::rosbag.*' should do exactly that, but the filter doesn't seem to match. The warning is still reported as error as with plain error.
  • even using PYTHONWARNINGS='error,ignore:::.*', which should in theory match any module, fails to match. Only removing the regex entirely like PYTHONWARNINGS='error,ignore:::' matches, but of course that is essentially equivalent to just PYTHONWARNINGS='ignore'.

Any ideas why the module regex is not matching at all?! Is this a Python distribution bug? I'm on Python 3.8.10 / Ubuntu 20.04.



Solution 1:[1]

As of Python 3.10, this is the intended behavior. Warning filters set through -W and PYTHONWARNINGS currently only match literal strings for the message and module.

This is a known discrepancy in the Python documentation, and is tracked in this CPython issue. There were some discussions and a PR to add regex support, but these ultimately went nowhere. This open PR adds further clarification to the docs.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 yut23