Skip to content
Open
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
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ ace2016
Adam Johnson
Adam Stewart
Adam Uhlir
Aditya Kumar
Aditya Tripuraneni
Ahn Ki-Wook
Akhilesh Ramakrishnan
Expand Down
1 change: 1 addition & 0 deletions changelog/15097.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
:meth:`WarningsRecorder.pop() <pytest.WarningsRecorder.pop>` now returns the first matching warning again when the recorded warnings have unrelated categories, instead of the last one.
20 changes: 10 additions & 10 deletions src/_pytest/recwarn.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,17 +213,17 @@ def pop(self, cls: type[Warning] = Warning) -> warnings.WarningMessage:
but not an instance of a child class of any other match.
Raises ``AssertionError`` if there is no match.
"""
best_idx: int | None = None
for i, w in enumerate(self._list):
if w.category == cls:
return self._list.pop(i) # exact match, stop looking
if issubclass(w.category, cls) and (
best_idx is None
or not issubclass(w.category, self._list[best_idx].category)
matches = [
(i, w.category)
for i, w in enumerate(self._list)
if issubclass(w.category, cls)
]
for i, category in matches:
if not any(
other is not category and issubclass(category, other)
for _, other in matches
):
best_idx = i
if best_idx is not None:
return self._list.pop(best_idx)
return self._list.pop(i)
__tracebackhide__ = True
raise AssertionError(f"{cls!r} not found in warning list")

Expand Down
19 changes: 19 additions & 0 deletions testing/test_recwarn.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,25 @@ def test_pop_finds_best_inexact_match(self):
_warn = record.pop(self.ParentWarning)
assert _warn.category is self.ChildWarning

def test_pop_finds_first_of_unrelated_matches(self):
with pytest.warns(Warning) as record:
self.raise_warnings_from_list(
[self.ChildWarning, UserWarning, DeprecationWarning]
)

assert record.pop().category is self.ChildWarning
assert record.pop().category is UserWarning
assert record.pop().category is DeprecationWarning

def test_pop_skips_child_of_later_match(self):
with pytest.warns(Warning) as record:
self.raise_warnings_from_list(
[self.ChildWarning, UserWarning, self.ParentWarning]
)

_warn = record.pop()
assert _warn.category is UserWarning


class TestWarningsRecorderChecker:
def test_recording(self) -> None:
Expand Down
Loading