Skip to content

Commit

Permalink
enhance excinfo.match failure output
Browse files Browse the repository at this point in the history
* now multiline and compares regexes
* warns on forgotten escaping
  • Loading branch information
RonnyPfannschmidt committed Oct 4, 2021
1 parent 2f6fdff commit 211ea2b
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 17 deletions.
9 changes: 5 additions & 4 deletions src/_pytest/_code/code.py
Expand Up @@ -665,10 +665,11 @@ def match(self, regexp: Union[str, Pattern[str]]) -> "Literal[True]":
If it matches `True` is returned, otherwise an `AssertionError` is raised.
"""
__tracebackhide__ = True
msg = "Regex pattern {!r} does not match {!r}."
if regexp == str(self.value):
msg += " Did you mean to `re.escape()` the regex?"
assert re.search(regexp, str(self.value)), msg.format(regexp, str(self.value))
value = str(self.value)
msg = f"Regex pattern did not match.\n Regex: {regexp!r}\n Input: {value!r}"
if regexp == value:
msg += "\n Did you mean to `re.escape()` the regex?"
assert re.search(regexp, value), msg
# Return True to allow for "assert excinfo.match()".
return True

Expand Down
14 changes: 8 additions & 6 deletions testing/code/test_excinfo.py
Expand Up @@ -420,18 +420,20 @@ def test_division_zero():
excinfo.match(r'[123]+')
"""
)
result = pytester.runpytest()
result = pytester.runpytest("--tb=short")
assert result.ret != 0

exc_msg = "Regex pattern '[[]123[]]+' does not match 'division by zero'."
result.stdout.fnmatch_lines([f"E * AssertionError: {exc_msg}"])
match = [
r"E .* AssertionError: Regex pattern did not match.",
r"E .* Regex: '\[123\]\+'",
r"E .* Input: 'division by zero'",
]
result.stdout.re_match_lines(match)
result.stdout.no_fnmatch_line("*__tracebackhide__ = True*")

result = pytester.runpytest("--fulltrace")
assert result.ret != 0
result.stdout.fnmatch_lines(
["*__tracebackhide__ = True*", f"E * AssertionError: {exc_msg}"]
)
result.stdout.re_match_lines([r".*__tracebackhide__ = True.*", *match])


class TestFormattedExcinfo:
Expand Down
17 changes: 10 additions & 7 deletions testing/python/raises.py
Expand Up @@ -191,10 +191,12 @@ def test_raises_match(self) -> None:
int("asdf")

msg = "with base 16"
expr = "Regex pattern {!r} does not match \"invalid literal for int() with base 10: 'asdf'\".".format(
msg
expr = (
"Regex pattern did not match.\n"
f" Regex: {msg!r}\n"
" Input: \"invalid literal for int() with base 10: 'asdf'\""
)
with pytest.raises(AssertionError, match=re.escape(expr)):
with pytest.raises(AssertionError, match="(?m)" + re.escape(expr)):
with pytest.raises(ValueError, match=msg):
int("asdf", base=10)

Expand All @@ -217,7 +219,7 @@ def test_match_failure_string_quoting(self):
with pytest.raises(AssertionError, match="'foo"):
raise AssertionError("'bar")
(msg,) = excinfo.value.args
assert msg == 'Regex pattern "\'foo" does not match "\'bar".'
assert msg == '''Regex pattern did not match.\n Regex: "'foo"\n Input: "'bar"'''

def test_match_failure_exact_string_message(self):
message = "Oh here is a message with (42) numbers in parameters"
Expand All @@ -226,9 +228,10 @@ def test_match_failure_exact_string_message(self):
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?"
"Regex pattern did not match.\n"
" Regex: 'Oh here is a message with (42) numbers in parameters'\n"
" Input: 'Oh here is a message with (42) numbers in parameters'\n"
" Did you mean to `re.escape()` the regex?"
)

def test_raises_match_wrong_type(self):
Expand Down

0 comments on commit 211ea2b

Please sign in to comment.