Skip to content

Commit b2f31c9

Browse files
committed
refactor: replace function-level pragma: no cover with precise line-level markers
Since tests now run servers in-process via threading, coverage.py tracks server-side code. Remove function-level pragmas that were flagged as wrongly marking covered code by strict-no-cover, and add line-level pragmas only to branches that remain truly uncovered. Files changed: - src/mcp/server/streamable_http.py: remove 17 function/line pragmas, add line-level pragmas to uncovered branches in _replay_events and message router exception handler - src/mcp/server/transport_security.py: remove 2 function pragmas (validate_host, validate_origin) + 5 line pragmas, add line-level pragmas to uncovered branches within those functions - src/mcp/server/session.py: remove 1 pragma from send_resource_updated No logic changes — only coverage annotation adjustments.
1 parent 8d659c6 commit b2f31c9

File tree

3 files changed

+55
-55
lines changed

3 files changed

+55
-55
lines changed

src/mcp/server/session.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ async def send_log_message(
222222
related_request_id,
223223
)
224224

225-
async def send_resource_updated(self, uri: str | AnyUrl) -> None: # pragma: no cover
225+
async def send_resource_updated(self, uri: str | AnyUrl) -> None:
226226
"""Send a resource updated notification."""
227227
await self.send_notification(
228228
types.ResourceUpdatedNotification(

src/mcp/server/streamable_http.py

Lines changed: 31 additions & 31 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: # pragma: no cover
180+
def close_sse_stream(self, request_id: RequestId) -> None:
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: # pragma: no cover
205205
send_stream.close()
206206
receive_stream.close()
207207

208-
def close_standalone_sse_stream(self) -> None: # pragma: no cover
208+
def close_standalone_sse_stream(self) -> None:
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,10 +240,10 @@ 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: # pragma: no cover
243+
async def close_stream_callback() -> None:
244244
self.close_sse_stream(request_id)
245245

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

249249
metadata = ServerMessageMetadata(
@@ -291,7 +291,7 @@ 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: # pragma: no cover
294+
if headers:
295295
response_headers.update(headers)
296296

297297
if self.mcp_session_id:
@@ -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: # pragma: no cover
345+
if event_message.event_id:
346346
event_data["id"] = event_message.event_id
347347

348348
return event_data
@@ -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: # pragma: no cover
470+
except ValidationError as e:
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): # pragma: no cover
496+
elif not await self._validate_request_headers(request, send):
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: # pragma: no cover
662+
if not has_sse:
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): # pragma: no cover
674+
if last_event_id := request.headers.get(LAST_EVENT_ID_HEADER):
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: # pragma: no cover
688+
if GET_STREAM_KEY in self._request_streams:
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: # pragma: no cover
717+
except Exception:
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: # pragma: no cover
794+
async def _handle_unsupported_request(self, request: Request, send: Send) -> None:
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: # pragma: no cover
827+
if not request_session_id:
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: # pragma: no cover
852+
if protocol_version is None:
853853
protocol_version = DEFAULT_NEGOTIATED_VERSION
854854

855855
# Check if the protocol version is supported
856-
if protocol_version not in SUPPORTED_PROTOCOL_VERSIONS: # pragma: no cover
856+
if protocol_version not in SUPPORTED_PROTOCOL_VERSIONS:
857857
supported_versions = ", ".join(SUPPORTED_PROTOCOL_VERSIONS)
858858
response = self._create_error_response(
859859
f"Bad Request: Unsupported protocol version: {protocol_version}. "
@@ -865,14 +865,14 @@ 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: # pragma: no cover
868+
async def _replay_events(self, last_event_id: str, request: Request, send: Send) -> None:
869869
"""Replays events that would have been sent after the specified event ID.
870870
871871
Only used when resumability is enabled.
872872
"""
873873
event_store = self._event_store
874874
if not event_store:
875-
return
875+
return # pragma: no cover
876876

877877
try:
878878
headers = {
@@ -921,9 +921,9 @@ async def send_event(event_message: EventMessage) -> None:
921921
await sse_stream_writer.send(event_data)
922922
except anyio.ClosedResourceError:
923923
# Expected when close_sse_stream() is called
924-
logger.debug("Replay SSE stream closed by close_sse_stream()")
924+
logger.debug("Replay SSE stream closed by close_sse_stream()") # pragma: no cover
925925
except Exception:
926-
logger.exception("Error in replay sender")
926+
logger.exception("Error in replay sender") # pragma: no cover
927927

928928
# Create and start EventSourceResponse
929929
response = EventSourceResponse(
@@ -934,20 +934,20 @@ async def send_event(event_message: EventMessage) -> None:
934934

935935
try:
936936
await response(request.scope, request.receive, send)
937-
except Exception:
938-
logger.exception("Error in replay response")
937+
except Exception: # pragma: no cover
938+
logger.exception("Error in replay response") # pragma: no cover
939939
finally:
940940
await sse_stream_writer.aclose()
941941
await sse_stream_reader.aclose()
942942

943-
except Exception:
944-
logger.exception("Error replaying events")
945-
response = self._create_error_response(
946-
"Error replaying events",
947-
HTTPStatus.INTERNAL_SERVER_ERROR,
948-
INTERNAL_ERROR,
949-
)
950-
await response(request.scope, request.receive, send)
943+
except Exception: # pragma: no cover
944+
logger.exception("Error replaying events") # pragma: no cover
945+
response = self._create_error_response( # pragma: no cover
946+
"Error replaying events", # pragma: no cover
947+
HTTPStatus.INTERNAL_SERVER_ERROR, # pragma: no cover
948+
INTERNAL_ERROR, # pragma: no cover
949+
) # pragma: no cover
950+
await response(request.scope, request.receive, send) # pragma: no cover
951951

952952
@asynccontextmanager
953953
async def connect(
@@ -1024,7 +1024,7 @@ async def message_router():
10241024
for message. Still processing message as the client
10251025
might reconnect and replay."""
10261026
)
1027-
except anyio.ClosedResourceError:
1027+
except anyio.ClosedResourceError: # pragma: no cover
10281028
if self._terminated:
10291029
logger.debug("Read stream closed by client")
10301030
else:

src/mcp/server/transport_security.py

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,15 @@ def __init__(self, settings: TransportSecuritySettings | None = None):
4040
# If not specified, disable DNS rebinding protection by default for backwards compatibility
4141
self.settings = settings or TransportSecuritySettings(enable_dns_rebinding_protection=False)
4242

43-
def _validate_host(self, host: str | None) -> bool: # pragma: no cover
43+
def _validate_host(self, host: str | None) -> bool:
4444
"""Validate the Host header against allowed values."""
4545
if not host:
46-
logger.warning("Missing Host header in request")
47-
return False
46+
logger.warning("Missing Host header in request") # pragma: no cover
47+
return False # pragma: no cover
4848

4949
# Check exact match first
5050
if host in self.settings.allowed_hosts:
51-
return True
51+
return True # pragma: no cover
5252

5353
# Check wildcard port patterns
5454
for allowed in self.settings.allowed_hosts:
@@ -59,30 +59,30 @@ def _validate_host(self, host: str | None) -> bool: # pragma: no cover
5959
if host.startswith(base_host + ":"):
6060
return True
6161

62-
logger.warning(f"Invalid Host header: {host}")
63-
return False
62+
logger.warning(f"Invalid Host header: {host}") # pragma: no cover
63+
return False # pragma: no cover
6464

65-
def _validate_origin(self, origin: str | None) -> bool: # pragma: no cover
65+
def _validate_origin(self, origin: str | None) -> bool:
6666
"""Validate the Origin header against allowed values."""
6767
# Origin can be absent for same-origin requests
6868
if not origin:
6969
return True
7070

7171
# Check exact match first
72-
if origin in self.settings.allowed_origins:
73-
return True
72+
if origin in self.settings.allowed_origins: # pragma: no cover
73+
return True # pragma: no cover
7474

7575
# Check wildcard port patterns
76-
for allowed in self.settings.allowed_origins:
77-
if allowed.endswith(":*"):
76+
for allowed in self.settings.allowed_origins: # pragma: no cover
77+
if allowed.endswith(":*"): # pragma: no cover
7878
# Extract base origin from pattern
79-
base_origin = allowed[:-2]
79+
base_origin = allowed[:-2] # pragma: no cover
8080
# Check if the actual origin starts with base origin and has a port
81-
if origin.startswith(base_origin + ":"):
82-
return True
81+
if origin.startswith(base_origin + ":"): # pragma: no cover
82+
return True # pragma: no cover
8383

84-
logger.warning(f"Invalid Origin header: {origin}")
85-
return False
84+
logger.warning(f"Invalid Origin header: {origin}") # pragma: no cover
85+
return False # pragma: no cover
8686

8787
def _validate_content_type(self, content_type: str | None) -> bool:
8888
"""Validate the Content-Type header for POST requests."""
@@ -103,14 +103,14 @@ async def validate_request(self, request: Request, is_post: bool = False) -> Res
103103
if not self.settings.enable_dns_rebinding_protection:
104104
return None
105105

106-
# Validate Host header # pragma: no cover
107-
host = request.headers.get("host") # pragma: no cover
108-
if not self._validate_host(host): # pragma: no cover
106+
# Validate Host header
107+
host = request.headers.get("host")
108+
if not self._validate_host(host):
109109
return Response("Invalid Host header", status_code=421) # pragma: no cover
110110

111-
# Validate Origin header # pragma: no cover
112-
origin = request.headers.get("origin") # pragma: no cover
113-
if not self._validate_origin(origin): # pragma: no cover
111+
# Validate Origin header
112+
origin = request.headers.get("origin")
113+
if not self._validate_origin(origin):
114114
return Response("Invalid Origin header", status_code=403) # pragma: no cover
115115

116-
return None # pragma: no cover
116+
return None

0 commit comments

Comments
 (0)