Skip to content

Commit d1b5751

Browse files
committed
test: exercise both handler branches so coverage stays at 100%
Record two warnings during handling and warn on only the first log record, so the handler's cap branch is taken in the passing run too (the repo enforces fail-under=100). Still asserts the handler is invoked once per recorded warning (twice), which a regressed build breaks by re-appending its own warning.
1 parent 39e1477 commit d1b5751

1 file changed

Lines changed: 19 additions & 12 deletions

File tree

tests/issues/test_3122_warning_loop.py

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,15 @@
99
1010
The fix snapshots the recorded warnings and logs them after leaving the
1111
``catch_warnings`` block, so handler-emitted warnings can no longer extend the
12-
iteration. This test drives ``_handle_message`` with a request that records one
13-
warning and a logging handler that itself warns on every record; the handler
14-
must be invoked exactly once. The handler stops re-warning after a cap so that
15-
the pre-fix infinite loop terminates and fails the assertion instead of hanging
16-
the test session.
12+
iteration.
13+
14+
The test records two warnings during handling and attaches a logging handler
15+
that itself warns on the first record only. After the fix each recorded warning
16+
is logged exactly once, so the handler is invoked twice (once per recorded
17+
warning) and no extra records appear. Before the fix, the handler's warning fed
18+
back into the iterated list and the handler was invoked a third time. Warning
19+
on only the first record keeps the handler from feeding the loop unboundedly, so
20+
a regressed build terminates and fails the assertion instead of hanging.
1721
"""
1822

1923
import logging
@@ -29,11 +33,10 @@
2933

3034

3135
class _WarningEmittingHandler(logging.Handler):
32-
"""A logging handler whose emit() raises a warning, mimicking e.g. a
33-
timestamp formatter that calls a deprecated API on every record. It stops
34-
after ``cap`` records so a regressed (looping) build still terminates."""
36+
"""A logging handler whose emit() raises a warning for the first ``cap``
37+
records, mimicking e.g. a timestamp formatter that warns per record."""
3538

36-
def __init__(self, cap: int = 100) -> None:
39+
def __init__(self, cap: int = 1) -> None:
3740
super().__init__()
3841
self.emit_count = 0
3942
self._cap = cap
@@ -45,14 +48,15 @@ def emit(self, record: logging.LogRecord) -> None:
4548

4649

4750
@pytest.mark.anyio
48-
async def test_handle_message_logs_each_warning_once_when_handler_warns():
51+
async def test_handle_message_logs_each_recorded_warning_once() -> None:
4952
server = Server("test-server")
5053

5154
session = Mock(spec=ServerSession)
5255
session.send_log_message = AsyncMock()
5356

5457
async def _handle_request_that_warns(*args: object, **kwargs: object) -> None:
55-
warnings.warn("warning raised while handling the request", stacklevel=1)
58+
warnings.warn("first warning raised while handling the request", stacklevel=1)
59+
warnings.warn("second warning raised while handling the request", stacklevel=1)
5660

5761
server._handle_request = _handle_request_that_warns # type: ignore[assignment]
5862

@@ -75,4 +79,7 @@ async def _handle_request_that_warns(*args: object, **kwargs: object) -> None:
7579
server_logger.removeHandler(handler)
7680
server_logger.setLevel(previous_level)
7781

78-
assert handler.emit_count == 1
82+
# Two warnings were recorded during handling, so the handler is invoked
83+
# exactly twice. A regressed build re-appends the handler's own warning and
84+
# invokes it a third time.
85+
assert handler.emit_count == 2

0 commit comments

Comments
 (0)