You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
There is the rule (PT011)[https://beta.ruff.rs/docs/rules/pytest-raises-too-broad/] which checks for pytest.raises() calls with a set of Exceptiones that are deemed as too broad and complains, when the pytest.raises() call is missing the match parameter.
Example from PT011:
importpytestdeftest_foo():
# Bad because too broad Exception with no exception info checkingwithpytest.raises(ValueError):
...
# Good according to PT011withpytest.raises(ValueError, match="expected message"):
...
Where is the problem
The problem with the match parameter is, that it is a regex under the hood, which is not that obvious. Or if you know it is, it is error prone. For example the Example above would also match Exception texts like Not the expected message which can be bad if the tested function raises different similar exceptions. One solution could be for this specific to put the ^ character at the beginning and the $ character at the end.
Because of the error prone nature of the match parameter I tend to save the exception in a variable and check the Exception info with a string comparison myself.
importpytestdeftest_foo():
withpytest.raises(ValueError) asexc:
# Checks if the message is exactly like the given string.assert"expected message"==str(exc.value)
Alternatively I also check with the in keyword, which in the PT011 case above has the same result, but is more obvious in what it does if you don't know that match is a regex.
importpytestdeftest_foo():
withpytest.raises(ValueError) asexc:
# Checks if the message contains the given string.assert"expected message"instr(exc.value)
New Rule request
I would like to propose a new rule, which checks if there is a broad exception, just like PT011 does, but instead complains, when the exception info is not checked.
This would need to consider
that the exc variable can have any name
that the comparison can be == or in
direct comparison like assert "expected message" == str(exc.value)
imo as long as the exception info variable is used in a following assert statement, it's plenty enough to avoid false-positives whilst minimizing false-negatives.
Using an assert instead of the match param is often desired for exact string matches and to avoid having to escape special regex characters.
withpytest.raises(ValueError, match="The complete error") asexcinfo: # oops, this is a partial match !function_that_raises()
withpytest.raises(ValueError, match="...") asexcinfo: # oops, this matches any 3+ character strings !function_that_raises()
A separate rule to avoid using match= with a non re.escape str could be nice (only disallow string literals, until Ruff gains multifile type information, pre-espaced strings can't be detected obviously)
Where we are
There is the rule (PT011)[https://beta.ruff.rs/docs/rules/pytest-raises-too-broad/] which checks for
pytest.raises()
calls with a set of Exceptiones that are deemed as too broad and complains, when thepytest.raises()
call is missing thematch
parameter.Example from PT011:
Where is the problem
The problem with the
match
parameter is, that it is a regex under the hood, which is not that obvious. Or if you know it is, it is error prone. For example the Example above would also match Exception texts likeNot the expected message
which can be bad if the tested function raises different similar exceptions. One solution could be for this specific to put the^
character at the beginning and the$
character at the end.Anthony has a video going more in depth on this https://www.youtube.com/watch?v=-1LXV_laNMs
Alternative solution(s)
Because of the error prone nature of the
match
parameter I tend to save the exception in a variable and check the Exception info with a string comparison myself.Alternatively I also check with the
in
keyword, which in the PT011 case above has the same result, but is more obvious in what it does if you don't know thatmatch
is a regex.New Rule request
I would like to propose a new rule, which checks if there is a broad exception, just like PT011 does, but instead complains, when the exception info is not checked.
This would need to consider
exc
variable can have any name==
orin
assert "expected message" == str(exc.value)
Perhaps also a rule to bann the
match
parameter would be nice, but I guess this would be too opinionated.The text was updated successfully, but these errors were encountered: