Skip to content
Open
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
1 change: 1 addition & 0 deletions changelog/8096.improvement.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Clearer error message for invalid ``-W`` filters, listing valid actions and the ``-Wait`` pitfall.
11 changes: 10 additions & 1 deletion src/_pytest/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2367,7 +2367,16 @@ def parse_warning_filter(
try:
action: warnings._ActionKind = warnings._getaction(action_) # type: ignore[attr-defined]
except warnings._OptionError as e:
raise UsageError(error_template.format(error=str(e))) from None
hint = (
" (choose from: default, error, ignore, always, module, once)."
" See https://docs.python.org/3/library/warnings.html#describing-warning-filters"
)
if action_ == "ait":
hint = (
" Note that '-W' takes a value, so '-Wait' is parsed as '-W ait'."
+ hint
)
raise UsageError(error_template.format(error=f"{e}{hint}")) from None
try:
category: type[Warning] = _resolve_warning_category(category_)
except ImportError:
Expand Down
13 changes: 13 additions & 0 deletions testing/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -3112,6 +3112,19 @@ def test_parse_warning_filter_failure(arg: str) -> None:
parse_warning_filter(arg, escape=True)


@pytest.mark.parametrize("arg", ["ait", "FOO"])
def test_parse_warning_filter_invalid_action_hint(arg: str) -> None:
"""Invalid -W actions show valid choices; the -Wait pitfall hint is scoped to that case."""
with pytest.raises(
pytest.UsageError, match=r"invalid action.*choose from"
) as exc_info:
parse_warning_filter(arg, escape=True)
if arg == "ait":
assert "-Wait" in str(exc_info.value)
else:
assert "-Wait" not in str(exc_info.value)


class TestDebugOptions:
def test_without_debug_does_not_write_log(self, pytester: Pytester) -> None:
result = pytester.runpytest()
Expand Down
17 changes: 17 additions & 0 deletions testing/test_warnings.py
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,23 @@ def test_invalid_regex_in_filterwarning(self, pytester: Pytester) -> None:
)


def test_dash_w_shows_wait_hint_on_usage_error(pytester: Pytester) -> None:
"""`-Wait` is parsed as `-W ait`; the hint should point at this."""
result = pytester.runpytest("-Wait")
assert result.ret == pytest.ExitCode.USAGE_ERROR
result.stderr.fnmatch_lines(
[
"ERROR: while parsing the following warning configuration:",
"",
" ait",
"",
"This error occurred:",
"",
"invalid action: 'ait'*-Wait*choose from*",
]
)


@pytest.mark.skip("not relevant until pytest 10.0")
@pytest.mark.parametrize("change_default", [None, "ini", "cmdline"])
def test_removed_in_x_warning_as_error(pytester: Pytester, change_default) -> None:
Expand Down
Loading