Skip to content

-W now takes precedence over filters in ini files #3947

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions changelog/3946.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Warning filters passed as command line options using ``-W`` now take precedence over filters defined in ``ini``
configuration files.
12 changes: 7 additions & 5 deletions src/_pytest/warnings.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,17 +67,19 @@ def catch_warnings_for_item(config, ihook, when, item):

Each warning captured triggers the ``pytest_warning_captured`` hook.
"""
args = config.getoption("pythonwarnings") or []
cmdline_filters = config.getoption("pythonwarnings") or []
inifilters = config.getini("filterwarnings")
with warnings.catch_warnings(record=True) as log:
filters_configured = args or inifilters or sys.warnoptions

for arg in args:
warnings._setoption(arg)
filters_configured = bool(cmdline_filters or inifilters or sys.warnoptions)

# filters should have this precedence: mark, cmdline options, ini
# filters should be applied in the inverse order of precedence
for arg in inifilters:
_setoption(warnings, arg)

for arg in cmdline_filters:
warnings._setoption(arg)

if item is not None:
for mark in item.iter_markers(name="filterwarnings"):
for arg in mark.args:
Expand Down
44 changes: 44 additions & 0 deletions testing/test_warnings.py
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,50 @@ def test_bar():
)


@pytest.mark.parametrize("ignore_on_cmdline", [True, False])
def test_option_precedence_cmdline_over_ini(testdir, ignore_on_cmdline):
"""filters defined in the command-line should take precedence over filters in ini files (#3946)."""
testdir.makeini(
"""
[pytest]
filterwarnings = error
"""
)
testdir.makepyfile(
"""
import warnings
def test():
warnings.warn(UserWarning('hello'))
"""
)
args = ["-W", "ignore"] if ignore_on_cmdline else []
result = testdir.runpytest(*args)
if ignore_on_cmdline:
result.stdout.fnmatch_lines(["* 1 passed in*"])
else:
result.stdout.fnmatch_lines(["* 1 failed in*"])


def test_option_precedence_mark(testdir):
"""Filters defined by marks should always take precedence (#3946)."""
testdir.makeini(
"""
[pytest]
filterwarnings = ignore
"""
)
testdir.makepyfile(
"""
import pytest, warnings
@pytest.mark.filterwarnings('error')
def test():
warnings.warn(UserWarning('hello'))
"""
)
result = testdir.runpytest("-W", "ignore")
result.stdout.fnmatch_lines(["* 1 failed in*"])


class TestDeprecationWarningsByDefault:
"""
Note: all pytest runs are executed in a subprocess so we don't inherit warning filters
Expand Down