Skip to content

Commit

Permalink
codecov and fix suggestion to re.escape string
Browse files Browse the repository at this point in the history
  • Loading branch information
jakkdl committed Nov 29, 2024
1 parent 2b98b2f commit f84d9d1
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 11 deletions.
51 changes: 43 additions & 8 deletions src/trio/_tests/test_testing_raisesgroup.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,14 @@ def test_catch_unwrapped_exceptions() -> None:
):
with RaisesGroup(ValueError, allow_unwrapped=True):
raise TypeError
with pytest.raises(
AssertionError,
match=wrap_escape(
"Raised exception did not match: Matcher(ValueError) does not match TypeError()",
),
):
with RaisesGroup(Matcher(ValueError), allow_unwrapped=True):
raise TypeError


def test_match() -> None:
Expand Down Expand Up @@ -413,6 +421,29 @@ def test_assert_message() -> None:
with RaisesGroup(Matcher(ValueError)):
raise ExceptionGroup("a", [TypeError()])

# suggest escaping
with pytest.raises(
AssertionError,
match=wrap_escape(
# TODO: this message should say the *group* didn't match
"Raised exception did not match: Regex pattern 'h(ell)o' did not match 'h(ell)o'\n"
"Did you mean to `re.escape()` the regex?",
),
):
with RaisesGroup(ValueError, match="h(ell)o"):
raise ExceptionGroup("h(ell)o", [ValueError()])
with pytest.raises(
AssertionError,
match=wrap_escape(
# Ideally the "did you mean to re.escape" should be indented twice
"Raised exception did not match: ValueError('h(ell)o'):\n"
" Matcher(match='h(ell)o'): Regex pattern 'h(ell)o' did not match 'h(ell)o'\n"
"Did you mean to `re.escape()` the regex?.",
),
):
with RaisesGroup(Matcher(match="h(ell)o")):
raise ExceptionGroup("", [ValueError("h(ell)o")])


def test_matcher() -> None:
with pytest.raises(
Expand Down Expand Up @@ -497,8 +528,8 @@ def check_errno_is_5(e: OSError) -> bool:
AssertionError,
match=wrap_escape(
# TODO: try to avoid printing the check function twice?
# it's very verbose with printing out memory location
# and/or don't print memory location and just print the name
# it's very verbose with printing out memory location.
# And/or don't print memory location and just print the name
"Raised exception did not match: OSError(6, ''):\n"
f" Matcher(OSError, check={check_errno_is_5!r}): check {check_errno_is_5!r} did not return True for OSError(6, '').",
),
Expand All @@ -521,12 +552,16 @@ def test_matcher_tostring() -> None:


def test_raisesgroup_tostring() -> None:
assert str(RaisesGroup(ValueError)) == "RaisesGroup(ValueError)"
assert (
str(RaisesGroup(RaisesGroup(ValueError)))
== "RaisesGroup(RaisesGroup(ValueError))"
)
assert str(RaisesGroup(Matcher(ValueError))) == "RaisesGroup(Matcher(ValueError))"
def check_str_and_repr(s: str) -> None:
evaled = eval(s)
assert s == str(evaled) == repr(evaled)

check_str_and_repr("RaisesGroup(ValueError)")
check_str_and_repr("RaisesGroup(RaisesGroup(ValueError))")
check_str_and_repr("RaisesGroup(Matcher(ValueError))")
check_str_and_repr("RaisesGroup(ValueError, allow_unwrapped=True)")
check_str_and_repr("RaisesGroup(ValueError, match='aoeu')")

assert (
str(RaisesGroup(ValueError, match="[a-z]", check=bool))
== f"RaisesGroup(ValueError, match='[a-z]', check={bool!r})"
Expand Down
9 changes: 6 additions & 3 deletions src/trio/testing/_raises_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,8 @@ def _check_match(match_expr: Pattern[str] | None, e: BaseException) -> str | Non
stringified_exception := _stringify_exception(e),
):
fail_reason = f"Regex pattern {_match_pattern(match_expr)!r} did not match {stringified_exception!r}"
if match_expr == stringified_exception:
fail_reason += "\n Did you mean to `re.escape()` the regex?"
if _match_pattern(match_expr) == stringified_exception:
fail_reason += "\nDid you mean to `re.escape()` the regex?"
return fail_reason
return None

Expand Down Expand Up @@ -646,16 +646,18 @@ def matches(
else:
self.fail_reason = f"{exc_val!r} is not an exception group, but would match with `allow_unwrapped=True`"
return False

if self.allow_unwrapped:
if isinstance(exp_exc, Matcher):
self.fail_reason = f"failed to match {exp_exc} with {exc_val}"
self.fail_reason = f"{exp_exc} does not match {exc_val!r}"
else:
assert isinstance(exp_exc, type)
self.fail_reason = f"{exc_val!r} is not an instance of {exp_exc!r}"
else:
self.fail_reason = f"{exc_val!r} is not an exception group"
return False

# TODO: if this fails, we should say the *group* message did not match
self.fail_reason = _check_match(self.match_expr, exc_val)
if self.fail_reason is not None:
return False
Expand Down Expand Up @@ -696,6 +698,7 @@ def matches(

# only run `self.check` once we know `exc_val` is correct. (see the types)
# unfortunately mypy isn't smart enough to recognize the above `for`s as narrowing.
# TODO: if this fails, we should say the *group* did not match
self.fail_reason = _check_check(self.check, exc_val) # type: ignore[arg-type]
return self.fail_reason is None

Expand Down

0 comments on commit f84d9d1

Please sign in to comment.