Skip to content

Commit 71ab623

Browse files
Clearer guidance on pytest.raise(match=...) failure (#7499)
1 parent 9c2c5d9 commit 71ab623

File tree

5 files changed

+21
-6
lines changed

5 files changed

+21
-6
lines changed

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ Kyle Altendorf
164164
Lawrence Mitchell
165165
Lee Kamentsky
166166
Lev Maximov
167+
Lewis Cowles
167168
Llandy Riveron Del Risco
168169
Loic Esteve
169170
Lukas Bednar

changelog/7489.improvement.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
The :func:`pytest.raises` function has a clearer error message when ``match`` equals the obtained string but is not a regex match. In this case it is suggested to escape the regex.

src/_pytest/_code/code.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -609,9 +609,10 @@ def match(self, regexp: "Union[str, Pattern]") -> "Literal[True]":
609609
If it matches `True` is returned, otherwise an `AssertionError` is raised.
610610
"""
611611
__tracebackhide__ = True
612-
assert re.search(
613-
regexp, str(self.value)
614-
), "Pattern {!r} does not match {!r}".format(regexp, str(self.value))
612+
msg = "Regex pattern {!r} does not match {!r}."
613+
if regexp == str(self.value):
614+
msg += " Did you mean to `re.escape()` the regex?"
615+
assert re.search(regexp, str(self.value)), msg.format(regexp, str(self.value))
615616
# Return True to allow for "assert excinfo.match()".
616617
return True
617618

testing/code/test_excinfo.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ def test_division_zero():
423423
result = testdir.runpytest()
424424
assert result.ret != 0
425425

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

testing/python/raises.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ def test_raises_match(self) -> None:
197197
int("asdf")
198198

199199
msg = "with base 16"
200-
expr = "Pattern {!r} does not match \"invalid literal for int() with base 10: 'asdf'\"".format(
200+
expr = "Regex pattern {!r} does not match \"invalid literal for int() with base 10: 'asdf'\".".format(
201201
msg
202202
)
203203
with pytest.raises(AssertionError, match=re.escape(expr)):
@@ -223,7 +223,19 @@ def test_match_failure_string_quoting(self):
223223
with pytest.raises(AssertionError, match="'foo"):
224224
raise AssertionError("'bar")
225225
(msg,) = excinfo.value.args
226-
assert msg == 'Pattern "\'foo" does not match "\'bar"'
226+
assert msg == 'Regex pattern "\'foo" does not match "\'bar".'
227+
228+
def test_match_failure_exact_string_message(self):
229+
message = "Oh here is a message with (42) numbers in parameters"
230+
with pytest.raises(AssertionError) as excinfo:
231+
with pytest.raises(AssertionError, match=message):
232+
raise AssertionError(message)
233+
(msg,) = excinfo.value.args
234+
assert msg == (
235+
"Regex pattern 'Oh here is a message with (42) numbers in "
236+
"parameters' does not match 'Oh here is a message with (42) "
237+
"numbers in parameters'. Did you mean to `re.escape()` the regex?"
238+
)
227239

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

0 commit comments

Comments
 (0)