Skip to content

Commit aad9e69

Browse files
committed
Update "pragma: no cover" locations for improved coverage
1 parent 5d22fab commit aad9e69

File tree

3 files changed

+36
-38
lines changed

3 files changed

+36
-38
lines changed

src/mcp/server/lowlevel/server.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -739,9 +739,7 @@ async def _handle_request(
739739
request_data = None
740740
close_sse_stream_cb = None
741741
close_standalone_sse_stream_cb = None
742-
if message.message_metadata is not None and isinstance(
743-
message.message_metadata, ServerMessageMetadata
744-
): # pragma: no cover
742+
if message.message_metadata is not None and isinstance(message.message_metadata, ServerMessageMetadata):
745743
request_data = message.message_metadata.request_context
746744
close_sse_stream_cb = message.message_metadata.close_sse_stream
747745
close_standalone_sse_stream_cb = message.message_metadata.close_standalone_sse_stream

src/mcp/server/streamable_http.py

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -328,19 +328,19 @@ def _create_json_response(
328328
headers=response_headers,
329329
)
330330

331-
def _get_session_id(self, request: Request) -> str | None: # pragma: no cover
331+
def _get_session_id(self, request: Request) -> str | None:
332332
"""Extract the session ID from request headers."""
333333
return request.headers.get(MCP_SESSION_ID_HEADER)
334334

335-
def _create_event_data(self, event_message: EventMessage) -> dict[str, str]: # pragma: no cover
335+
def _create_event_data(self, event_message: EventMessage) -> dict[str, str]:
336336
"""Create event data dictionary from an EventMessage."""
337337
event_data = {
338338
"event": "message",
339339
"data": event_message.message.model_dump_json(by_alias=True, exclude_none=True),
340340
}
341341

342342
# If an event ID was provided, include it
343-
if event_message.event_id:
343+
if event_message.event_id: # pragma: no cover
344344
event_data["id"] = event_message.event_id
345345

346346
return event_data
@@ -381,9 +381,9 @@ async def handle_request(self, scope: Scope, receive: Receive, send: Send) -> No
381381

382382
if request.method == "POST":
383383
await self._handle_post_request(scope, request, receive, send)
384-
elif request.method == "GET": # pragma: no cover
384+
elif request.method == "GET":
385385
await self._handle_get_request(request, send)
386-
elif request.method == "DELETE": # pragma: no cover
386+
elif request.method == "DELETE":
387387
await self._handle_delete_request(request, send)
388388
else: # pragma: no cover
389389
await self._handle_unsupported_request(request, send)
@@ -470,14 +470,14 @@ async def _handle_post_request(self, scope: Scope, request: Request, receive: Re
470470
# Check if this is an initialization request
471471
is_initialization_request = isinstance(message, JSONRPCRequest) and message.method == "initialize"
472472

473-
if is_initialization_request: # pragma: no cover
473+
if is_initialization_request:
474474
# Check if the server already has an established session
475475
if self.mcp_session_id:
476476
# Check if request has a session ID
477477
request_session_id = self._get_session_id(request)
478478

479479
# If request has a session ID but doesn't match, return 404
480-
if request_session_id and request_session_id != self.mcp_session_id:
480+
if request_session_id and request_session_id != self.mcp_session_id: # pragma: no cover
481481
response = self._create_error_response(
482482
"Not Found: Invalid or expired session ID",
483483
HTTPStatus.NOT_FOUND,
@@ -488,7 +488,7 @@ async def _handle_post_request(self, scope: Scope, request: Request, receive: Re
488488
return
489489

490490
# For notifications and responses only, return 202 Accepted
491-
if not isinstance(message, JSONRPCRequest): # pragma: no cover
491+
if not isinstance(message, JSONRPCRequest):
492492
# Create response object and send it
493493
response = self._create_json_response(
494494
None,
@@ -561,14 +561,14 @@ async def _handle_post_request(self, scope: Scope, request: Request, receive: Re
561561
await response(scope, receive, send)
562562
finally:
563563
await self._clean_up_memory_streams(request_id)
564-
else: # pragma: no cover
564+
else:
565565
# Create SSE stream
566566
sse_stream_writer, sse_stream_reader = anyio.create_memory_object_stream[dict[str, str]](0)
567567

568568
# Store writer reference so close_sse_stream() can close it
569569
self._sse_stream_writers[request_id] = sse_stream_writer
570570

571-
async def sse_writer():
571+
async def sse_writer(): # pragma: lax no cover
572572
# Get the request ID from the incoming request message
573573
try:
574574
async with sse_stream_writer, request_stream_reader:
@@ -617,7 +617,7 @@ async def sse_writer():
617617
# Then send the message to be processed by the server
618618
session_message = self._create_session_message(message, request, request_id, protocol_version)
619619
await writer.send(session_message)
620-
except Exception:
620+
except Exception: # pragma: no cover
621621
logger.exception("SSE response error")
622622
await sse_stream_writer.aclose()
623623
await self._clean_up_memory_streams(request_id)
@@ -636,33 +636,33 @@ async def sse_writer():
636636
await writer.send(Exception(err))
637637
return
638638

639-
async def _handle_get_request(self, request: Request, send: Send) -> None: # pragma: no cover
639+
async def _handle_get_request(self, request: Request, send: Send) -> None:
640640
"""Handle GET request to establish SSE.
641641
642642
This allows the server to communicate to the client without the client
643643
first sending data via HTTP POST. The server can send JSON-RPC requests
644644
and notifications on this stream.
645645
"""
646646
writer = self._read_stream_writer
647-
if writer is None:
647+
if writer is None: # pragma: no cover
648648
raise ValueError("No read stream writer available. Ensure connect() is called first.")
649649

650650
# Validate Accept header - must include text/event-stream
651651
_, has_sse = self._check_accept_headers(request)
652652

653-
if not has_sse:
653+
if not has_sse: # pragma: no cover
654654
response = self._create_error_response(
655655
"Not Acceptable: Client must accept text/event-stream",
656656
HTTPStatus.NOT_ACCEPTABLE,
657657
)
658658
await response(request.scope, request.receive, send)
659659
return
660660

661-
if not await self._validate_request_headers(request, send):
661+
if not await self._validate_request_headers(request, send): # pragma: no cover
662662
return
663663

664664
# Handle resumability: check for Last-Event-ID header
665-
if last_event_id := request.headers.get(LAST_EVENT_ID_HEADER):
665+
if last_event_id := request.headers.get(LAST_EVENT_ID_HEADER): # pragma: no cover
666666
await self._replay_events(last_event_id, request, send)
667667
return
668668

@@ -676,7 +676,7 @@ async def _handle_get_request(self, request: Request, send: Send) -> None: # pr
676676
headers[MCP_SESSION_ID_HEADER] = self.mcp_session_id
677677

678678
# Check if we already have an active GET stream
679-
if GET_STREAM_KEY in self._request_streams:
679+
if GET_STREAM_KEY in self._request_streams: # pragma: no cover
680680
response = self._create_error_response(
681681
"Conflict: Only one SSE stream is allowed per session",
682682
HTTPStatus.CONFLICT,
@@ -696,7 +696,7 @@ async def standalone_sse_writer():
696696

697697
async with sse_stream_writer, standalone_stream_reader:
698698
# Process messages from the standalone stream
699-
async for event_message in standalone_stream_reader:
699+
async for event_message in standalone_stream_reader: # pragma: lax no cover
700700
# For the standalone stream, we handle:
701701
# - JSONRPCNotification (server sends notifications to client)
702702
# - JSONRPCRequest (server sends requests to client)
@@ -705,7 +705,7 @@ async def standalone_sse_writer():
705705
# Send the message via SSE
706706
event_data = self._create_event_data(event_message)
707707
await sse_stream_writer.send(event_data)
708-
except Exception:
708+
except Exception: # pragma: no cover
709709
logger.exception("Error in standalone SSE writer")
710710
finally:
711711
logger.debug("Closing standalone SSE writer")
@@ -721,17 +721,17 @@ async def standalone_sse_writer():
721721
try:
722722
# This will send headers immediately and establish the SSE connection
723723
await response(request.scope, request.receive, send)
724-
except Exception:
724+
except Exception: # pragma: lax no cover
725725
logger.exception("Error in standalone SSE response")
726726
await self._clean_up_memory_streams(GET_STREAM_KEY)
727727
finally:
728728
await sse_stream_writer.aclose()
729729
await sse_stream_reader.aclose()
730730

731-
async def _handle_delete_request(self, request: Request, send: Send) -> None: # pragma: no cover
731+
async def _handle_delete_request(self, request: Request, send: Send) -> None:
732732
"""Handle DELETE requests for explicit session termination."""
733733
# Validate session ID
734-
if not self.mcp_session_id:
734+
if not self.mcp_session_id: # pragma: no cover
735735
# If no session ID set, return Method Not Allowed
736736
response = self._create_error_response(
737737
"Method Not Allowed: Session termination not supported",
@@ -740,7 +740,7 @@ async def _handle_delete_request(self, request: Request, send: Send) -> None: #
740740
await response(request.scope, request.receive, send)
741741
return
742742

743-
if not await self._validate_request_headers(request, send):
743+
if not await self._validate_request_headers(request, send): # pragma: no cover
744744
return
745745

746746
await self.terminate()
@@ -798,24 +798,24 @@ async def _handle_unsupported_request(self, request: Request, send: Send) -> Non
798798
)
799799
await response(request.scope, request.receive, send)
800800

801-
async def _validate_request_headers(self, request: Request, send: Send) -> bool: # pragma: no cover
801+
async def _validate_request_headers(self, request: Request, send: Send) -> bool: # pragma: lax no cover
802802
if not await self._validate_session(request, send):
803803
return False
804804
if not await self._validate_protocol_version(request, send):
805805
return False
806806
return True
807807

808-
async def _validate_session(self, request: Request, send: Send) -> bool: # pragma: no cover
808+
async def _validate_session(self, request: Request, send: Send) -> bool:
809809
"""Validate the session ID in the request."""
810-
if not self.mcp_session_id:
810+
if not self.mcp_session_id: # pragma: no cover
811811
# If we're not using session IDs, return True
812812
return True
813813

814814
# Get the session ID from the request headers
815815
request_session_id = self._get_session_id(request)
816816

817817
# If no session ID provided but required, return error
818-
if not request_session_id:
818+
if not request_session_id: # pragma: no cover
819819
response = self._create_error_response(
820820
"Bad Request: Missing session ID",
821821
HTTPStatus.BAD_REQUEST,
@@ -824,7 +824,7 @@ async def _validate_session(self, request: Request, send: Send) -> bool: # prag
824824
return False
825825

826826
# If session ID doesn't match, return error
827-
if request_session_id != self.mcp_session_id:
827+
if request_session_id != self.mcp_session_id: # pragma: no cover
828828
response = self._create_error_response(
829829
"Not Found: Invalid or expired session ID",
830830
HTTPStatus.NOT_FOUND,
@@ -834,17 +834,17 @@ async def _validate_session(self, request: Request, send: Send) -> bool: # prag
834834

835835
return True
836836

837-
async def _validate_protocol_version(self, request: Request, send: Send) -> bool: # pragma: no cover
837+
async def _validate_protocol_version(self, request: Request, send: Send) -> bool:
838838
"""Validate the protocol version header in the request."""
839839
# Get the protocol version from the request headers
840840
protocol_version = request.headers.get(MCP_PROTOCOL_VERSION_HEADER)
841841

842842
# If no protocol version provided, assume default version
843-
if protocol_version is None:
843+
if protocol_version is None: # pragma: no cover
844844
protocol_version = DEFAULT_NEGOTIATED_VERSION
845845

846846
# Check if the protocol version is supported
847-
if protocol_version not in SUPPORTED_PROTOCOL_VERSIONS:
847+
if protocol_version not in SUPPORTED_PROTOCOL_VERSIONS: # pragma: no cover
848848
supported_versions = ", ".join(SUPPORTED_PROTOCOL_VERSIONS)
849849
response = self._create_error_response(
850850
f"Bad Request: Unsupported protocol version: {protocol_version}. "
@@ -1006,10 +1006,10 @@ async def message_router():
10061006
try:
10071007
# Send both the message and the event ID
10081008
await self._request_streams[request_stream_id][0].send(EventMessage(message, event_id))
1009-
except ( # pragma: no cover
1009+
except (
10101010
anyio.BrokenResourceError,
10111011
anyio.ClosedResourceError,
1012-
):
1012+
): # pragma: no cover
10131013
# Stream might be closed, remove from registry
10141014
self._request_streams.pop(request_stream_id, None)
10151015
else: # pragma: no cover

src/mcp/server/streamable_http_manager.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ async def _handle_stateful_request(self, scope: Scope, receive: Receive, send: S
181181
request_mcp_session_id = request.headers.get(MCP_SESSION_ID_HEADER)
182182

183183
# Existing session case
184-
if request_mcp_session_id is not None and request_mcp_session_id in self._server_instances: # pragma: no cover
184+
if request_mcp_session_id is not None and request_mcp_session_id in self._server_instances:
185185
transport = self._server_instances[request_mcp_session_id]
186186
logger.debug("Session already exists, handling request directly")
187187
await transport.handle_request(scope, receive, send)
@@ -261,5 +261,5 @@ class StreamableHTTPASGIApp:
261261
def __init__(self, session_manager: StreamableHTTPSessionManager):
262262
self.session_manager = session_manager
263263

264-
async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: # pragma: no cover
264+
async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
265265
await self.session_manager.handle_request(scope, receive, send)

0 commit comments

Comments
 (0)