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 changelog/14189.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Nested usage of :meth:`caplog.filtering <pytest.LogCaptureFixture.filtering>` no longer removes filters early if they were already present.
12 changes: 8 additions & 4 deletions src/_pytest/logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -600,11 +600,15 @@ def filtering(self, filter_: logging.Filter) -> Generator[None]:

.. versionadded:: 7.5
"""
self.handler.addFilter(filter_)
try:
already_present = filter_ in self.handler.filters
if already_present:
yield
finally:
self.handler.removeFilter(filter_)
else:
try:
self.handler.addFilter(filter_)
yield
finally:
self.handler.removeFilter(filter_)


@fixture
Expand Down
34 changes: 34 additions & 0 deletions testing/logging/test_fixture.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,40 @@ def filter(self, record: logging.LogRecord) -> bool:
assert unfiltered_tuple == ("test_fixture", 20, "handler call")


class DropAllFilter(logging.Filter):
def filter(self, record: logging.LogRecord) -> bool:
return False


def test_with_statement_nested_filtering(caplog: pytest.LogCaptureFixture) -> None:
drop_all = DropAllFilter()

with caplog.filtering(drop_all):
logger.warning("Will not be captured")
with caplog.filtering(drop_all):
logger.warning("Will also not be captured")
logger.warning("Should not be captured either")

assert caplog.records == []


def test_with_statement_filtering_already_present(
caplog: pytest.LogCaptureFixture,
) -> None:
drop_all = DropAllFilter()

caplog.handler.addFilter(drop_all)
try:
with caplog.filtering(drop_all):
logger.warning("Should not be captured")

# After context manager, filter should STILL be present because it was already there
logger.warning("Should still not be captured")
assert caplog.records == []
finally:
caplog.handler.removeFilter(drop_all)


@pytest.mark.parametrize(
"level_str,expected_disable_level",
[
Expand Down