diff --git a/changelog/14488.bugfix.rst b/changelog/14488.bugfix.rst new file mode 100644 index 00000000000..b54324ae9e3 --- /dev/null +++ b/changelog/14488.bugfix.rst @@ -0,0 +1 @@ +Raise a descriptive :class:`RuntimeError` instead of a :class:`KeyError` when accessing ``caplog.handler`` before it has been initialized. diff --git a/src/_pytest/logging.py b/src/_pytest/logging.py index 2a22c9eb4aa..d138f8600dd 100644 --- a/src/_pytest/logging.py +++ b/src/_pytest/logging.py @@ -449,7 +449,10 @@ def _finalize(self) -> None: @property def handler(self) -> LogCaptureHandler: """Get the logging handler used by the fixture.""" - return self._item.stash[caplog_handler_key] + handler = self._item.stash.get(caplog_handler_key, None) + if handler is None: + raise RuntimeError("caplog handler was not initialized for this test item") + return handler def get_records( self, when: Literal["setup", "call", "teardown"] diff --git a/testing/logging/test_fixture.py b/testing/logging/test_fixture.py index c98b7d84258..b8e29f053d2 100644 --- a/testing/logging/test_fixture.py +++ b/testing/logging/test_fixture.py @@ -5,6 +5,7 @@ from collections.abc import Iterator import logging +from _pytest.logging import caplog_handler_key from _pytest.logging import caplog_records_key from _pytest.pytester import Pytester import pytest @@ -508,3 +509,10 @@ def test_that_fails(request, caplog): ["*Print message*", "*INFO log message*", "*WARNING log message*"] ) assert result.ret == 1 + + +def test_caplog_missing_handler_raises_error(caplog: pytest.LogCaptureFixture) -> None: + del caplog._item.stash[caplog_handler_key] + + with pytest.raises(RuntimeError, match="caplog handler was not initialized"): + _ = caplog.handler