Skip to content

Commit

Permalink
Merge pull request #7573 from nicoddemus/backport-7571
Browse files Browse the repository at this point in the history
[6.0.x] logging: fix capture handler level not reset on teardown after caplog.set_level()
  • Loading branch information
nicoddemus committed Jul 29, 2020
2 parents d46fe88 + f9d5f6e commit 3d2c114
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 2 deletions.
4 changes: 4 additions & 0 deletions src/_pytest/logging.py
Expand Up @@ -345,6 +345,7 @@ def __init__(self, item: nodes.Node) -> None:
"""Creates a new funcarg."""
self._item = item
# dict of log name -> log level
self._initial_handler_level = None # type: Optional[int]
self._initial_logger_levels = {} # type: Dict[Optional[str], int]

def _finalize(self) -> None:
Expand All @@ -353,6 +354,8 @@ def _finalize(self) -> None:
This restores the log levels changed by :meth:`set_level`.
"""
# restore log levels
if self._initial_handler_level is not None:
self.handler.setLevel(self._initial_handler_level)
for logger_name, level in self._initial_logger_levels.items():
logger = logging.getLogger(logger_name)
logger.setLevel(level)
Expand Down Expand Up @@ -434,6 +437,7 @@ def set_level(self, level: Union[int, str], logger: Optional[str] = None) -> Non
# save the original log-level to restore it during teardown
self._initial_logger_levels.setdefault(logger, logger_obj.level)
logger_obj.setLevel(level)
self._initial_handler_level = self.handler.level
self.handler.setLevel(level)

@contextmanager
Expand Down
35 changes: 33 additions & 2 deletions testing/logging/test_fixture.py
Expand Up @@ -2,6 +2,7 @@

import pytest
from _pytest.logging import caplog_records_key
from _pytest.pytester import Testdir

logger = logging.getLogger(__name__)
sublogger = logging.getLogger(__name__ + ".baz")
Expand All @@ -27,8 +28,11 @@ def test_change_level(caplog):
assert "CRITICAL" in caplog.text


def test_change_level_undo(testdir):
"""Ensure that 'set_level' is undone after the end of the test"""
def test_change_level_undo(testdir: Testdir) -> None:
"""Ensure that 'set_level' is undone after the end of the test.
Tests the logging output themselves (affacted both by logger and handler levels).
"""
testdir.makepyfile(
"""
import logging
Expand All @@ -50,6 +54,33 @@ def test2(caplog):
result.stdout.no_fnmatch_line("*log from test2*")


def test_change_level_undos_handler_level(testdir: Testdir) -> None:
"""Ensure that 'set_level' is undone after the end of the test (handler).
Issue #7569. Tests the handler level specifically.
"""
testdir.makepyfile(
"""
import logging
def test1(caplog):
assert caplog.handler.level == 0
caplog.set_level(41)
assert caplog.handler.level == 41
def test2(caplog):
assert caplog.handler.level == 0
def test3(caplog):
assert caplog.handler.level == 0
caplog.set_level(43)
assert caplog.handler.level == 43
"""
)
result = testdir.runpytest()
result.assert_outcomes(passed=3)


def test_with_statement(caplog):
with caplog.at_level(logging.INFO):
logger.debug("handler DEBUG level")
Expand Down

0 comments on commit 3d2c114

Please sign in to comment.