bluenote10
bluenote10

Reputation: 26600

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:

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.

Upvotes: 6

Views: 741

Answers (2)

reddot
reddot

Reputation: 985

For ones looking for a workaround to suppress warnings in third-party modules and keep shown for developed packages and/or modules. Say I have developing mypackage. I use a shell wrapper runner script that does following:

FLT="$(cd "./src"; find mypackage/ -name '*.py' | \
    sed -e 's/\.py//g' -e 's/\/__init__//g' -e 's/\//./g' | \
    { while read module; do
        echo "default:::$module"
    done; echo "default:::__main__"; } | paste -sd,)"

export PYTHONWARNINGS="ignore,$FLT"

Upvotes: 0

yut23
yut23

Reputation: 3064

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.

Upvotes: 8

Related Questions