Skip to content

Commit

Permalink
capture warning when exception is raised (fix pytest-dev#9036)
Browse files Browse the repository at this point in the history
  • Loading branch information
Cheukting committed Jun 22, 2023
1 parent 1e32a4b commit 5ee778c
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 18 deletions.
1 change: 1 addition & 0 deletions changelog/9036.bugfix.rst
@@ -0,0 +1 @@
``pytest.warns`` and similar functions now capture warnings when an exception is raised inside a ``with`` block.
35 changes: 17 additions & 18 deletions src/_pytest/recwarn.py
Expand Up @@ -291,23 +291,22 @@ def found_str():
return pformat([record.message for record in self], indent=2)

# only check if we're not currently handling an exception
if exc_type is None and exc_val is None and exc_tb is None:
if self.expected_warning is not None:
if not any(issubclass(r.category, self.expected_warning) for r in self):
__tracebackhide__ = True
if self.expected_warning is not None:
if not any(issubclass(r.category, self.expected_warning) for r in self):
__tracebackhide__ = True
fail(
f"DID NOT WARN. No warnings of type {self.expected_warning} were emitted.\n"
f"The list of emitted warnings is: {found_str()}."
)
elif self.match_expr is not None:
for r in self:
if issubclass(r.category, self.expected_warning):
if re.compile(self.match_expr).search(str(r.message)):
break
else:
fail(
f"DID NOT WARN. No warnings of type {self.expected_warning} were emitted.\n"
f"The list of emitted warnings is: {found_str()}."
)
elif self.match_expr is not None:
for r in self:
if issubclass(r.category, self.expected_warning):
if re.compile(self.match_expr).search(str(r.message)):
break
else:
fail(
f"""\
f"""\
DID NOT WARN. No warnings of type {self.expected_warning} matching the regex were emitted.
Regex: {self.match_expr}
Emitted warnings: {found_str()}"""
)
Regex: {self.match_expr}
Emitted warnings: {found_str()}"""
)
21 changes: 21 additions & 0 deletions testing/test_recwarn.py
Expand Up @@ -403,3 +403,24 @@ def test_warns_context_manager_with_kwargs(self) -> None:
with pytest.warns(UserWarning, foo="bar"): # type: ignore
pass
assert "Unexpected keyword arguments" in str(excinfo.value)

def test_catch_warning_within_raise(self) -> None:
def f():
warnings.warn("some warning", category=FutureWarning)
raise ValueError("some exception")

with pytest.raises(pytest.fail.Exception):
with pytest.warns(SyntaxWarning, match="some warning"):
with pytest.raises(ValueError, match="some exception"):
f()

with pytest.raises(pytest.fail.Exception):
with pytest.raises(ValueError, match="some exception"):
with pytest.warns(SyntaxWarning, match="some warning"):
f()

with pytest.raises(pytest.fail.Exception):
with pytest.raises(ValueError, match="some exception"), pytest.warns(
SyntaxWarning, match="some warning"
):
f()

0 comments on commit 5ee778c

Please sign in to comment.