Skip to content

Instantly share code, notes, and snippets.

@matthewfeickert
Last active May 27, 2022 22:02
Show Gist options
  • Save matthewfeickert/cb906f6e7b746f9d641aa807b004d065 to your computer and use it in GitHub Desktop.
Save matthewfeickert/cb906f6e7b746f9d641aa807b004d065 to your computer and use it in GitHub Desktop.
Example of regex in pytest ini options failing

How to properly escape regex for pytest filterwarnings?

Hi. This question is motivated by scikit-hep/pyhf#1873 and is similar to subject matter to pytest-dev/pytest#8759 but I think different enough that I'm still going to ask.

Here's a GitHub Gist with the example files as well.

In scikit-hep/pyhf#1873 I have a set of warnings that I want to be able to filter with filterwarnings and with a simple regex that works fine with warnings.filterwarnings

# std_filterwarnings.py
import warnings

message_true_divide = "invalid value encountered in true_divide"
message_divide = "invalid value encountered in divide"

message_ignore_regex = "invalid value encountered in (?:true_)?divide"

warnings.filterwarnings("ignore", message=message_ignore_regex, category=Warning)

warnings.warn(message_true_divide)
warnings.warn(message_divide)

I now want to apply this to my pytest configuration. Using pytest v7.1.2

$ cat requirements.txt
numpy==1.22.4
pytest==7.1.2

and setting up the pytest ini options in pyproject.toml, the following

[tool.pytest.ini_options]
minversion = "7.0"
xfail_strict = true
addopts = [
    "-ra",
    "--showlocals",
    "--strict-config",
]
log_cli_level = "info"
filterwarnings = [
    "error",
    'ignore:invalid value encountered in true_divide:RuntimeWarning',
]

works as expected for

# test_example.py
import numpy as np


def test_example():
    a = np.asarray([0.0])
    b = np.asarray([0.0])
    assert a / b
$ pytest
================================================================= test session starts ==================================================================
platform linux -- Python 3.10.3, pytest-7.1.2, pluggy-1.0.0
rootdir: /home/feickert/Code/debug/pytest-filterwarnings, configfile: pyproject.toml
collected 1 item

test_example.py .                                                                                                                                [100%]

================================================================== 1 passed in 0.08s ===================================================================

However, if I now try to use the regex that worked in std_filterwarnings.py

[tool.pytest.ini_options]
minversion = "7.0"
xfail_strict = true
addopts = [
    "-ra",
    "--showlocals",
    "--strict-config",
]
log_cli_level = "info"
filterwarnings = [
    "error",
    'ignore:invalid value encountered in (?:true_)?divide:RuntimeWarning',
]

pytest immediately AttributeErrors out as the regex is not getting escaped properly

$ pytest
ERROR: while parsing the following warning configuration:

  ignore:invalid value encountered in (?:true_)?divide:RuntimeWarning

This error occurred:

Traceback (most recent call last):
  File "/home/feickert/.pyenv/versions/filterwarnings/lib/python3.10/site-packages/_pytest/config/__init__.py", line 1638, in parse_warning_filter
    category: Type[Warning] = _resolve_warning_category(category_)
  File "/home/feickert/.pyenv/versions/filterwarnings/lib/python3.10/site-packages/_pytest/config/__init__.py", line 1677, in _resolve_warning_category
    cat = getattr(m, klass)
AttributeError: module 'builtins' has no attribute 'true_)?divide'

I am clearly messing up the regex somehow and need to escape it, but it isn't clear to me why and what I should be doing. I assume that the : in (?:true_)?divide needs to be escaped, given the AttributeError. Can someone explain to me what the proper approach here is?

This also doesn't appear to be an TOML issue as the following pytest.ini also produces the error

# pytest.ini
[pytest]
minversion = 7.0
xfail_strict = true
addopts =
    -ra
    --showlocals
    --strict-config
log_cli_level = info
filterwarnings =
    error
    ignore:invalid value encountered in (?:true_)?divide:RuntimeWarning
[tool.pytest.ini_options]
minversion = "7.0"
xfail_strict = true
addopts = [
"-ra",
"--showlocals",
"--strict-config",
]
log_cli_level = "info"
filterwarnings = [
"error",
# 'ignore:invalid value encountered in true_divide:RuntimeWarning',
'ignore:invalid value encountered in (true_)?divide:RuntimeWarning',
]
numpy==1.22.4
pytest==7.1.2
import warnings
message_true_divide = "invalid value encountered in true_divide"
message_divide = "invalid value encountered in divide"
message_ignore_regex = "invalid value encountered in (?:true_)?divide"
warnings.filterwarnings("ignore", message=message_ignore_regex, category=Warning)
warnings.warn(message_true_divide)
warnings.warn(message_divide)
import numpy as np
def test_example():
a = np.asarray([0.0])
b = np.asarray([0.0])
assert a / b
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment