'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 amodule
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 plainerror
. - even using
PYTHONWARNINGS='error,ignore:::.*'
, which should in theory match any module, fails to match. Only removing the regex entirely likePYTHONWARNINGS='error,ignore:::'
matches, but of course that is essentially equivalent to justPYTHONWARNINGS='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 |