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
17 changes: 16 additions & 1 deletion src/_pytest/mark/structures.py
Original file line number Diff line number Diff line change
Expand Up @@ -426,9 +426,24 @@ def __call__(
*conditions: Union[str, bool],
reason: str = ...,
run: bool = ...,
raises: Union[Type[BaseException], Tuple[Type[BaseException], ...]] = ...,
raises: Union[Type[BaseException], Tuple[Type[BaseException], ...]] = (),
strict: bool = ...,
) -> MarkDecorator:
__tracebackhide__ = True
if raises is None:
raise UsageError(
"Passing `raises=None` to xfail is an error, because it's "
"impossible to raise an exception which is not an instance of any type. "
"Raising exceptions is already understood as failing the test, so you "
"don't need any special code to say 'this should never raise an exception'."
)
elif isinstance(raises, tuple) and not raises:
raise UsageError(
"Passing `raises=()` to xfail is an error, because it's impossible "
"to raise an exception which is not an instance of any type. Raising "
"exceptions is already understood as failing the test, so you don't need "
"any special code to say 'this should never raise an exception'."
)
...

class _ParametrizeMarkDecorator(MarkDecorator):
Expand Down
13 changes: 13 additions & 0 deletions src/_pytest/python_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,19 @@ def approx(expected, rel=None, abs=None, nan_ok: bool = False) -> ApproxBase:

__tracebackhide__ = True

if expected_exception is None:
raise UsageError(
"Passing `expected_exception=None` is invalid, as it is ambiguous for "
"what exceptions pytest should catch. To assert that no exception is "
"expected, simply execute the block without using `pytest.raises()`."
)
if isinstance(expected_exception, tuple) and not expected_exception:
raise UsageError(
"Passing an empty tuple `expected_exception=()` is invalid, as it would "
"not specify any exceptions to catch. To assert that no exception is "
"expected, simply execute the block without using `pytest.raises()`."
)

if isinstance(expected, Decimal):
cls: Type[ApproxBase] = ApproxDecimal
elif isinstance(expected, Mapping):
Expand Down
14 changes: 14 additions & 0 deletions src/_pytest/recwarn.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,20 @@ def deprecated_call(
one for each warning raised.
"""
__tracebackhide__ = True
if expected_warning is None:
raise TypeError(
"Passing `expected_warning=None` is an error, because it's "
"impossible to emit a warning which is not an instance of any type. "
"To assert that no warnings are emitted, use `pytest.warns(None)` to explicitly "
"declare that no warnings are expected."
)
elif isinstance(expected_warning, tuple) and not expected_warning:
raise TypeError(
"Passing `expected_warning=()` is an error, because it's "
"impossible to emit a warning which is not an instance of any type. "
"To assert that no warnings are emitted, use `pytest.warns(None)` to explicitly "
"declare that no warnings are expected."
)
if func is not None:
args = (func,) + args
return warns((DeprecationWarning, PendingDeprecationWarning), *args, **kwargs)
Expand Down