Description
What's the problem this feature will solve?
When writing parameterised tests, we often find that code within the test should either raise or not raise an Exception based on the parameters. The docs suggest passing the context manager itself as a parameter, either pytest.raises(X)
or contextlib.nullcontext
. This can make test code less concise than it could otherwise be.
Describe the solution you'd like
pytest.raises(None)
could be overloaded to behave semantically the same as contextlib.nullcontext
.
@pytest.mark.parametrize('x, exc', [(2, None), (0, ZeroDivisionError)])
def test_divide(x, exc):
with pytest.raises(exc):
print(1/x)
With Hypothesis tests, this becomes even more useful:
@given(x=st.integers())
def test_divide(x):
with pytest.raises(ZeroDivisionError if x == 0 else None):
print(1/x)
Alternative Solutions
https://docs.pytest.org/en/stable/example/parametrize.html#parametrizing-conditional-raising is the documented solution, but I think this could be improved
Additional context
I'm happy to try implementing this, but wanted to raise a discussion first. It looks like something like a NullRaisesExc(AbstractRaises)
could be returned by raises(None)
.
I would also propose that the 'legacy form' where we pass a callable to raises
would not gain this new syntactic sugar.
Activity
andyclegg commentedon May 15, 2025
This may also help with #13410 , though this was not the motivation for submitting this issue.
[-]pytest.raises(None) should work like contextlib.nullcontext[/-][+]Support conditional raising with pytest.raises(None)[/+]Zac-HD commentedon May 15, 2025
See #1830 #4324 #4682 #5165 #9402 #9404 #10654 etc.; we've considered this carefully and think it would be net-negative for our users overall.