Skip to content
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

Feature/raises clearer guidance #7499

Merged
merged 2 commits into from
Jul 15, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ Kyle Altendorf
Lawrence Mitchell
Lee Kamentsky
Lev Maximov
Lewis Cowles
Llandy Riveron Del Risco
Loic Esteve
Lukas Bednar
Expand Down
1 change: 1 addition & 0 deletions changelog/7489.improvement.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The :func:`pytest.raises` function has a clearer error message when ``match`` matches the obtained string but is not regex-escaped.
Lewiscowles1986 marked this conversation as resolved.
Show resolved Hide resolved
8 changes: 5 additions & 3 deletions src/_pytest/_code/code.py
Original file line number Diff line number Diff line change
Expand Up @@ -609,9 +609,11 @@ def match(self, regexp: "Union[str, Pattern]") -> "Literal[True]":
If it matches `True` is returned, otherwise an `AssertionError` is raised.
"""
__tracebackhide__ = True
assert re.search(
regexp, str(self.value)
), "Pattern {!r} does not match {!r}".format(regexp, str(self.value))
regextest = re.search(regexp, str(self.value))
msg = "Regex pattern {!r} does not match {!r}."
if regexp == str(self.value):
msg += " Did you mean to `re.escape()` the regex?"
assert regextest, msg.format(regexp, str(self.value))
Lewiscowles1986 marked this conversation as resolved.
Show resolved Hide resolved
# Return True to allow for "assert excinfo.match()".
return True

Expand Down
2 changes: 1 addition & 1 deletion testing/code/test_excinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ def test_division_zero():
result = testdir.runpytest()
assert result.ret != 0

exc_msg = "Pattern '[[]123[]]+' does not match 'division by zero'"
exc_msg = "Regex pattern '[[]123[]]+' does not match 'division by zero'."
result.stdout.fnmatch_lines(["E * AssertionError: {}".format(exc_msg)])
result.stdout.no_fnmatch_line("*__tracebackhide__ = True*")

Expand Down
16 changes: 14 additions & 2 deletions testing/python/raises.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ def test_raises_match(self) -> None:
int("asdf")

msg = "with base 16"
expr = "Pattern {!r} does not match \"invalid literal for int() with base 10: 'asdf'\"".format(
expr = "Regex pattern {!r} does not match \"invalid literal for int() with base 10: 'asdf'\".".format(
msg
)
with pytest.raises(AssertionError, match=re.escape(expr)):
Expand All @@ -223,7 +223,19 @@ def test_match_failure_string_quoting(self):
with pytest.raises(AssertionError, match="'foo"):
raise AssertionError("'bar")
(msg,) = excinfo.value.args
assert msg == 'Pattern "\'foo" does not match "\'bar"'
assert msg == 'Regex pattern "\'foo" does not match "\'bar".'

def test_match_failure_exact_string_message(self):
message = "Oh here is a message with (42) numbers in parameters"
with pytest.raises(AssertionError) as excinfo:
with pytest.raises(AssertionError, match=message):
raise AssertionError(message)
(msg,) = excinfo.value.args
assert msg == (
"Regex pattern 'Oh here is a message with (42) numbers in "
"parameters' does not match 'Oh here is a message with (42) "
"numbers in parameters'. Did you mean to `re.escape()` the regex?"
)

def test_raises_match_wrong_type(self):
"""Raising an exception with the wrong type and match= given.
Expand Down