Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions src/_pytest/raises.py
Original file line number Diff line number Diff line change
Expand Up @@ -519,12 +519,10 @@ def _check_match(self, e: BaseException) -> bool:
self._fail_reason = ("\n" if diff[0][0] == "-" else "") + "\n".join(diff)
return False

# I don't love "Regex"+"Input" vs something like "expected regex"+"exception message"
# when they're similar it's not always obvious which is which
self._fail_reason = (
f"Regex pattern did not match{maybe_specify_type}.\n"
f" Regex: {_match_pattern(self.match)!r}\n"
f" Input: {stringified_exception!r}"
f" Expected regex: {_match_pattern(self.match)!r}\n"
f" Actual message: {stringified_exception!r}"
)
if _match_pattern(self.match) == stringified_exception:
self._fail_reason += "\n Did you mean to `re.escape()` the regex?"
Expand Down
13 changes: 8 additions & 5 deletions testing/python/raises.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,8 +253,8 @@ def test_raises_match(self) -> None:
msg = "with base 16"
expr = (
"Regex pattern did not match.\n"
f" Regex: {msg!r}\n"
" Input: \"invalid literal for int() with base 10: 'asdf'\""
f" Expected regex: {msg!r}\n"
f" Actual message: \"invalid literal for int() with base 10: 'asdf'\""
)
with pytest.raises(AssertionError, match="^" + re.escape(expr) + "$"):
with pytest.raises(ValueError, match=msg):
Expand Down Expand Up @@ -289,7 +289,10 @@ def test_match_failure_string_quoting(self):
with pytest.raises(AssertionError, match="'foo"):
raise AssertionError("'bar")
(msg,) = excinfo.value.args
assert msg == '''Regex pattern did not match.\n Regex: "'foo"\n Input: "'bar"'''
assert (
msg
== '''Regex pattern did not match.\n Expected regex: "'foo"\n Actual message: "'bar"'''
)

def test_match_failure_exact_string_message(self):
message = "Oh here is a message with (42) numbers in parameters"
Expand All @@ -299,8 +302,8 @@ def test_match_failure_exact_string_message(self):
(msg,) = excinfo.value.args
assert msg == (
"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"
" Expected regex: 'Oh here is a message with (42) numbers in parameters'\n"
" Actual message: 'Oh here is a message with (42) numbers in parameters'\n"
" Did you mean to `re.escape()` the regex?"
)

Expand Down
88 changes: 45 additions & 43 deletions testing/python/raises_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,8 +382,8 @@ def test_match() -> None:
with (
fails_raises_group(
"Regex pattern did not match the `ExceptionGroup()`.\n"
" Regex: 'foo'\n"
" Input: 'bar'"
" Expected regex: 'foo'\n"
" Actual message: 'bar'"
),
RaisesGroup(ValueError, match="foo"),
):
Expand All @@ -396,8 +396,8 @@ def test_match() -> None:
with (
fails_raises_group(
"Regex pattern did not match the `ExceptionGroup()`.\n"
" Regex: 'foo'\n"
" Input: 'bar'\n"
" Expected regex: 'foo'\n"
" Actual message: 'bar'\n"
" but matched the expected `ValueError`.\n"
" You might want `RaisesGroup(RaisesExc(ValueError, match='foo'))`"
),
Expand Down Expand Up @@ -570,8 +570,8 @@ def test_assert_message() -> None:
" ExceptionGroup('', [RuntimeError()]):\n"
" RaisesGroup(ValueError): `RuntimeError()` is not an instance of `ValueError`\n"
" RaisesGroup(ValueError, match='a'): Regex pattern did not match the `ExceptionGroup()`.\n"
" Regex: 'a'\n"
" Input: ''\n"
" Expected regex: 'a'\n"
" Actual message: ''\n"
" RuntimeError():\n"
" RaisesGroup(ValueError): `RuntimeError()` is not an exception group\n"
" RaisesGroup(ValueError, match='a'): `RuntimeError()` is not an exception group",
Expand Down Expand Up @@ -634,8 +634,8 @@ def test_assert_message() -> None:
fails_raises_group(
# TODO: did not match Exceptiongroup('h(ell)o', ...) ?
"Raised exception group did not match: Regex pattern did not match the `ExceptionGroup()`.\n"
" Regex: 'h(ell)o'\n"
" Input: 'h(ell)o'\n"
" Expected regex: 'h(ell)o'\n"
" Actual message: 'h(ell)o'\n"
" Did you mean to `re.escape()` the regex?",
add_prefix=False, # to see the full structure
),
Expand All @@ -645,8 +645,8 @@ def test_assert_message() -> None:
with (
fails_raises_group(
"RaisesExc(match='h(ell)o'): Regex pattern did not match.\n"
" Regex: 'h(ell)o'\n"
" Input: 'h(ell)o'\n"
" Expected regex: 'h(ell)o'\n"
" Actual message: 'h(ell)o'\n"
" Did you mean to `re.escape()` the regex?",
),
RaisesGroup(RaisesExc(match="h(ell)o")),
Expand Down Expand Up @@ -799,8 +799,8 @@ def test_suggestion_on_nested_and_brief_error() -> None:
"The following raised exceptions did not find a match\n"
" ExceptionGroup('^hello', [Exception()]):\n"
" RaisesGroup(Exception, match='^hello'): Regex pattern did not match the `ExceptionGroup()`.\n"
" Regex: '^hello'\n"
" Input: '^hello'\n"
" Expected regex: '^hello'\n"
" Actual message: '^hello'\n"
" Did you mean to `re.escape()` the regex?\n"
" Unexpected nested `ExceptionGroup()`, expected `ValueError`"
),
Expand Down Expand Up @@ -830,8 +830,8 @@ def test_assert_message_nested() -> None:
" RaisesGroup(ValueError): `TypeError()` is not an instance of `ValueError`\n"
" RaisesGroup(RaisesGroup(ValueError)): RaisesGroup(ValueError): `TypeError()` is not an exception group\n"
" RaisesGroup(RaisesExc(TypeError, match='foo')): RaisesExc(TypeError, match='foo'): Regex pattern did not match.\n"
" Regex: 'foo'\n"
" Input: 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'\n"
" Expected regex: 'foo'\n"
" Actual message: 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'\n"
" RaisesGroup(TypeError, ValueError): 1 matched exception. Too few exceptions raised, found no match for: [ValueError]\n"
" ExceptionGroup('Exceptions from Trio nursery', [TypeError('cccccccccccccccccccccccccccccc'), TypeError('dddddddddddddddddddddddddddddd')]):\n"
" RaisesGroup(ValueError): \n"
Expand All @@ -856,12 +856,12 @@ def test_assert_message_nested() -> None:
" The following raised exceptions did not find a match\n"
" TypeError('cccccccccccccccccccccccccccccc'):\n"
" RaisesExc(TypeError, match='foo'): Regex pattern did not match.\n"
" Regex: 'foo'\n"
" Input: 'cccccccccccccccccccccccccccccc'\n"
" Expected regex: 'foo'\n"
" Actual message: 'cccccccccccccccccccccccccccccc'\n"
" TypeError('dddddddddddddddddddddddddddddd'):\n"
" RaisesExc(TypeError, match='foo'): Regex pattern did not match.\n"
" Regex: 'foo'\n"
" Input: 'dddddddddddddddddddddddddddddd'\n"
" Expected regex: 'foo'\n"
" Actual message: 'dddddddddddddddddddddddddddddd'\n"
" RaisesGroup(TypeError, ValueError): \n"
" 1 matched exception. \n"
" The following expected exceptions did not find a match:\n"
Expand Down Expand Up @@ -945,8 +945,8 @@ def test_misordering_example() -> None:
" It matches `ValueError` which was paired with `ValueError('foo')`\n"
" It matches `ValueError` which was paired with `ValueError('foo')`\n"
" RaisesExc(ValueError, match='foo'): Regex pattern did not match.\n"
" Regex: 'foo'\n"
" Input: 'bar'\n"
" Expected regex: 'foo'\n"
" Actual message: 'bar'\n"
"There exist a possible match when attempting an exhaustive check, but RaisesGroup uses a greedy algorithm. Please make your expected exceptions more stringent with `RaisesExc` etc so the greedy algorithm can function."
),
RaisesGroup(
Expand Down Expand Up @@ -1036,34 +1036,34 @@ def test_identity_oopsies() -> None:
"The following raised exceptions did not find a match\n"
" ValueError('foo'):\n"
" RaisesExc(match='bar'): Regex pattern did not match.\n"
" Regex: 'bar'\n"
" Input: 'foo'\n"
" Expected regex: 'bar'\n"
" Actual message: 'foo'\n"
" RaisesExc(match='bar'): Regex pattern did not match.\n"
" Regex: 'bar'\n"
" Input: 'foo'\n"
" Expected regex: 'bar'\n"
" Actual message: 'foo'\n"
" RaisesExc(match='bar'): Regex pattern did not match.\n"
" Regex: 'bar'\n"
" Input: 'foo'\n"
" Expected regex: 'bar'\n"
" Actual message: 'foo'\n"
" ValueError('foo'):\n"
" RaisesExc(match='bar'): Regex pattern did not match.\n"
" Regex: 'bar'\n"
" Input: 'foo'\n"
" Expected regex: 'bar'\n"
" Actual message: 'foo'\n"
" RaisesExc(match='bar'): Regex pattern did not match.\n"
" Regex: 'bar'\n"
" Input: 'foo'\n"
" Expected regex: 'bar'\n"
" Actual message: 'foo'\n"
" RaisesExc(match='bar'): Regex pattern did not match.\n"
" Regex: 'bar'\n"
" Input: 'foo'\n"
" Expected regex: 'bar'\n"
" Actual message: 'foo'\n"
" ValueError('foo'):\n"
" RaisesExc(match='bar'): Regex pattern did not match.\n"
" Regex: 'bar'\n"
" Input: 'foo'\n"
" Expected regex: 'bar'\n"
" Actual message: 'foo'\n"
" RaisesExc(match='bar'): Regex pattern did not match.\n"
" Regex: 'bar'\n"
" Input: 'foo'\n"
" Expected regex: 'bar'\n"
" Actual message: 'foo'\n"
" RaisesExc(match='bar'): Regex pattern did not match.\n"
" Regex: 'bar'\n"
" Input: 'foo'"
" Expected regex: 'bar'\n"
" Actual message: 'foo'"
),
RaisesGroup(m, m, m),
):
Expand Down Expand Up @@ -1120,7 +1120,9 @@ def test_raisesexc() -> None:
# currently RaisesGroup says "Raised exception did not match" but RaisesExc doesn't...
with pytest.raises(
AssertionError,
match=wrap_escape("Regex pattern did not match.\n Regex: 'foo'\n Input: 'bar'"),
match=wrap_escape(
"Regex pattern did not match.\n Expected regex: 'foo'\n Actual message: 'bar'"
),
):
with RaisesExc(TypeError, match="foo"):
raise TypeError("bar")
Expand All @@ -1132,8 +1134,8 @@ def test_raisesexc_match() -> None:
with (
fails_raises_group(
"RaisesExc(ValueError, match='foo'): Regex pattern did not match.\n"
" Regex: 'foo'\n"
" Input: 'bar'"
" Expected regex: 'foo'\n"
" Actual message: 'bar'"
),
RaisesGroup(RaisesExc(ValueError, match="foo")),
):
Expand All @@ -1145,8 +1147,8 @@ def test_raisesexc_match() -> None:
with (
fails_raises_group(
"RaisesExc(match='foo'): Regex pattern did not match.\n"
" Regex: 'foo'\n"
" Input: 'bar'"
" Expected regex: 'foo'\n"
" Actual message: 'bar'"
),
RaisesGroup(RaisesExc(match="foo")),
):
Expand Down
Loading