Skip to content

Commit 7942963

Browse files
committed
fix: use pragma lax no cover for non-deterministic coverage lines
Server code running in-thread has non-deterministic coverage for exception handlers and conditional branches depending on thread timing. Use lax annotation which is excluded by coverage.py but not flagged by strict-no-cover.
1 parent 1252ff1 commit 7942963

File tree

1 file changed

+25
-25
lines changed

1 file changed

+25
-25
lines changed

src/mcp/server/streamable_http.py

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ def is_terminated(self) -> bool:
177177
"""Check if this transport has been explicitly terminated."""
178178
return self._terminated
179179

180-
def close_sse_stream(self, request_id: RequestId) -> None:
180+
def close_sse_stream(self, request_id: RequestId) -> None: # pragma: lax no cover
181181
"""Close SSE connection for a specific request without terminating the stream.
182182
183183
This method closes the HTTP connection for the specified request, triggering
@@ -205,7 +205,7 @@ def close_sse_stream(self, request_id: RequestId) -> None:
205205
send_stream.close()
206206
receive_stream.close()
207207

208-
def close_standalone_sse_stream(self) -> None:
208+
def close_standalone_sse_stream(self) -> None: # pragma: lax no cover
209209
"""Close the standalone GET SSE stream, triggering client reconnection.
210210
211211
This method closes the HTTP connection for the standalone GET stream used
@@ -240,18 +240,18 @@ def _create_session_message(
240240
# Only provide close callbacks when client supports resumability
241241
if self._event_store and protocol_version >= "2025-11-25":
242242

243-
async def close_stream_callback() -> None:
243+
async def close_stream_callback() -> None: # pragma: lax no cover
244244
self.close_sse_stream(request_id)
245245

246-
async def close_standalone_stream_callback() -> None:
246+
async def close_standalone_stream_callback() -> None: # pragma: lax no cover
247247
self.close_standalone_sse_stream()
248248

249249
metadata = ServerMessageMetadata(
250250
request_context=request,
251251
close_sse_stream=close_stream_callback,
252252
close_standalone_sse_stream=close_standalone_stream_callback,
253253
)
254-
else:
254+
else: # pragma: lax no cover
255255
metadata = ServerMessageMetadata(request_context=request)
256256

257257
return SessionMessage(message, metadata=metadata)
@@ -291,10 +291,10 @@ def _create_error_response(
291291
) -> Response:
292292
"""Create an error response with a simple string message."""
293293
response_headers = {"Content-Type": CONTENT_TYPE_JSON}
294-
if headers:
294+
if headers: # pragma: lax no cover
295295
response_headers.update(headers)
296296

297-
if self.mcp_session_id:
297+
if self.mcp_session_id: # pragma: lax no cover
298298
response_headers[MCP_SESSION_ID_HEADER] = self.mcp_session_id
299299

300300
# Return a properly formatted JSON error response
@@ -342,7 +342,7 @@ def _create_event_data(self, event_message: EventMessage) -> dict[str, str]:
342342
}
343343

344344
# If an event ID was provided, include it
345-
if event_message.event_id:
345+
if event_message.event_id: # pragma: lax no cover
346346
event_data["id"] = event_message.event_id
347347

348348
return event_data
@@ -372,7 +372,7 @@ async def handle_request(self, scope: Scope, receive: Receive, send: Send) -> No
372372
await error_response(scope, receive, send)
373373
return
374374

375-
if self._terminated:
375+
if self._terminated: # pragma: lax no cover
376376
# If the session has been terminated, return 404 Not Found
377377
response = self._create_error_response(
378378
"Not Found: Session has been terminated",
@@ -387,7 +387,7 @@ async def handle_request(self, scope: Scope, receive: Receive, send: Send) -> No
387387
await self._handle_get_request(request, send)
388388
elif request.method == "DELETE":
389389
await self._handle_delete_request(request, send)
390-
else:
390+
else: # pragma: lax no cover
391391
await self._handle_unsupported_request(request, send)
392392

393393
def _check_accept_headers(self, request: Request) -> tuple[bool, bool]:
@@ -467,7 +467,7 @@ async def _handle_post_request(self, scope: Scope, request: Request, receive: Re
467467

468468
try:
469469
message = jsonrpc_message_adapter.validate_python(raw_message, by_name=False)
470-
except ValidationError as e:
470+
except ValidationError as e: # pragma: lax no cover
471471
response = self._create_error_response(
472472
f"Validation error: {str(e)}",
473473
HTTPStatus.BAD_REQUEST,
@@ -493,7 +493,7 @@ async def _handle_post_request(self, scope: Scope, request: Request, receive: Re
493493
)
494494
await response(scope, receive, send)
495495
return
496-
elif not await self._validate_request_headers(request, send):
496+
elif not await self._validate_request_headers(request, send): # pragma: lax no cover
497497
return
498498

499499
# For notifications and responses only, return 202 Accepted
@@ -659,7 +659,7 @@ async def _handle_get_request(self, request: Request, send: Send) -> None:
659659
# Validate Accept header - must include text/event-stream
660660
_, has_sse = self._check_accept_headers(request)
661661

662-
if not has_sse:
662+
if not has_sse: # pragma: lax no cover
663663
response = self._create_error_response(
664664
"Not Acceptable: Client must accept text/event-stream",
665665
HTTPStatus.NOT_ACCEPTABLE,
@@ -671,7 +671,7 @@ async def _handle_get_request(self, request: Request, send: Send) -> None:
671671
return
672672

673673
# Handle resumability: check for Last-Event-ID header
674-
if last_event_id := request.headers.get(LAST_EVENT_ID_HEADER):
674+
if last_event_id := request.headers.get(LAST_EVENT_ID_HEADER): # pragma: lax no cover
675675
await self._replay_events(last_event_id, request, send)
676676
return
677677

@@ -685,7 +685,7 @@ async def _handle_get_request(self, request: Request, send: Send) -> None:
685685
headers[MCP_SESSION_ID_HEADER] = self.mcp_session_id
686686

687687
# Check if we already have an active GET stream
688-
if GET_STREAM_KEY in self._request_streams:
688+
if GET_STREAM_KEY in self._request_streams: # pragma: lax no cover
689689
response = self._create_error_response(
690690
"Conflict: Only one SSE stream is allowed per session",
691691
HTTPStatus.CONFLICT,
@@ -714,7 +714,7 @@ async def standalone_sse_writer():
714714
# Send the message via SSE
715715
event_data = self._create_event_data(event_message)
716716
await sse_stream_writer.send(event_data)
717-
except Exception:
717+
except Exception: # pragma: lax no cover
718718
logger.exception("Error in standalone SSE writer")
719719
finally:
720720
logger.debug("Closing standalone SSE writer")
@@ -791,7 +791,7 @@ async def terminate(self) -> None:
791791
# During cleanup, we catch all exceptions since streams might be in various states
792792
logger.debug(f"Error closing streams: {e}")
793793

794-
async def _handle_unsupported_request(self, request: Request, send: Send) -> None:
794+
async def _handle_unsupported_request(self, request: Request, send: Send) -> None: # pragma: lax no cover
795795
"""Handle unsupported HTTP methods."""
796796
headers = {
797797
"Content-Type": CONTENT_TYPE_JSON,
@@ -824,7 +824,7 @@ async def _validate_session(self, request: Request, send: Send) -> bool:
824824
request_session_id = self._get_session_id(request)
825825

826826
# If no session ID provided but required, return error
827-
if not request_session_id:
827+
if not request_session_id: # pragma: lax no cover
828828
response = self._create_error_response(
829829
"Bad Request: Missing session ID",
830830
HTTPStatus.BAD_REQUEST,
@@ -849,11 +849,11 @@ async def _validate_protocol_version(self, request: Request, send: Send) -> bool
849849
protocol_version = request.headers.get(MCP_PROTOCOL_VERSION_HEADER)
850850

851851
# If no protocol version provided, assume default version
852-
if protocol_version is None:
852+
if protocol_version is None: # pragma: lax no cover
853853
protocol_version = DEFAULT_NEGOTIATED_VERSION
854854

855855
# Check if the protocol version is supported
856-
if protocol_version not in SUPPORTED_PROTOCOL_VERSIONS:
856+
if protocol_version not in SUPPORTED_PROTOCOL_VERSIONS: # pragma: lax no cover
857857
supported_versions = ", ".join(SUPPORTED_PROTOCOL_VERSIONS)
858858
response = self._create_error_response(
859859
f"Bad Request: Unsupported protocol version: {protocol_version}. "
@@ -865,7 +865,7 @@ async def _validate_protocol_version(self, request: Request, send: Send) -> bool
865865

866866
return True
867867

868-
async def _replay_events(self, last_event_id: str, request: Request, send: Send) -> None:
868+
async def _replay_events(self, last_event_id: str, request: Request, send: Send) -> None: # pragma: lax no cover
869869
"""Replays events that would have been sent after the specified event ID.
870870
871871
Only used when resumability is enabled.
@@ -922,7 +922,7 @@ async def send_event(event_message: EventMessage) -> None:
922922
except anyio.ClosedResourceError:
923923
# Expected when close_sse_stream() is called
924924
logger.debug("Replay SSE stream closed by close_sse_stream()") # pragma: no cover
925-
except Exception:
925+
except Exception: # pragma: lax no cover
926926
logger.exception("Error in replay sender") # pragma: no cover
927927

928928
# Create and start EventSourceResponse
@@ -991,7 +991,7 @@ async def message_router():
991991
if isinstance(message, JSONRPCResponse | JSONRPCError) and message.id is not None:
992992
target_request_id = str(message.id)
993993
# Extract related_request_id from meta if it exists
994-
elif (
994+
elif ( # pragma: lax no cover
995995
session_message.metadata is not None
996996
and isinstance(
997997
session_message.metadata,
@@ -1018,7 +1018,7 @@ async def message_router():
10181018
except (anyio.BrokenResourceError, anyio.ClosedResourceError): # pragma: lax no cover
10191019
# Stream might be closed, remove from registry
10201020
self._request_streams.pop(request_stream_id, None)
1021-
else:
1021+
else: # pragma: lax no cover
10221022
logger.debug(
10231023
f"""Request stream {request_stream_id} not found
10241024
for message. Still processing message as the client
@@ -1027,7 +1027,7 @@ async def message_router():
10271027
except anyio.ClosedResourceError:
10281028
if self._terminated:
10291029
logger.debug("Read stream closed by client")
1030-
else:
1030+
else: # pragma: lax no cover
10311031
logger.exception("Unexpected closure of read stream in message router")
10321032
except Exception: # pragma: lax no cover
10331033
logger.exception("Error in message router")

0 commit comments

Comments
 (0)