Skip to content

Commit 01f5876

Browse files
update uv.lock & add pragmas
1 parent 7d3674a commit 01f5876

File tree

5 files changed

+93
-23
lines changed

5 files changed

+93
-23
lines changed

src/mcp/client/streamable_http.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -358,11 +358,11 @@ async def _handle_sse_response(
358358
if is_complete:
359359
await response.aclose()
360360
return # Normal completion, no reconnect needed
361-
except Exception as e:
361+
except Exception as e: # pragma: no cover
362362
logger.debug(f"SSE stream ended: {e}")
363363

364364
# Stream ended without response - reconnect if we received an event with ID
365-
if last_event_id is not None:
365+
if last_event_id is not None: # pragma: no branch
366366
logger.info("SSE stream disconnected, reconnecting...")
367367
await self._handle_reconnection(ctx, last_event_id, retry_interval_ms)
368368

@@ -375,7 +375,7 @@ async def _handle_reconnection(
375375
) -> None:
376376
"""Reconnect with Last-Event-ID to resume stream after server disconnect."""
377377
# Bail if max retries exceeded
378-
if attempt >= MAX_RECONNECTION_ATTEMPTS:
378+
if attempt >= MAX_RECONNECTION_ATTEMPTS: # pragma: no cover
379379
logger.debug(f"Max reconnection attempts ({MAX_RECONNECTION_ATTEMPTS}) exceeded")
380380
return
381381

@@ -388,7 +388,7 @@ async def _handle_reconnection(
388388

389389
# Extract original request ID to map responses
390390
original_request_id = None
391-
if isinstance(ctx.session_message.message.root, JSONRPCRequest):
391+
if isinstance(ctx.session_message.message.root, JSONRPCRequest): # pragma: no branch
392392
original_request_id = ctx.session_message.message.root.id
393393

394394
try:
@@ -407,7 +407,7 @@ async def _handle_reconnection(
407407
reconnect_retry_ms = retry_interval_ms
408408

409409
async for sse in event_source.aiter_sse():
410-
if sse.id:
410+
if sse.id: # pragma: no branch
411411
reconnect_last_event_id = sse.id
412412
if sse.retry is not None:
413413
reconnect_retry_ms = sse.retry
@@ -425,7 +425,7 @@ async def _handle_reconnection(
425425
# Stream ended again without response - reconnect again (reset attempt counter)
426426
logger.info("SSE stream disconnected, reconnecting...")
427427
await self._handle_reconnection(ctx, reconnect_last_event_id, reconnect_retry_ms, 0)
428-
except Exception as e:
428+
except Exception as e: # pragma: no cover
429429
logger.debug(f"Reconnection failed: {e}")
430430
# Try to reconnect again if we still have an event ID
431431
await self._handle_reconnection(ctx, last_event_id, retry_interval_ms, attempt + 1)

src/mcp/server/fastmcp/server.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1299,7 +1299,7 @@ async def close_sse_stream(self) -> None:
12991299
This is a no-op if not using StreamableHTTP transport with event_store.
13001300
The callback is only available when event_store is configured.
13011301
"""
1302-
if self._request_context and self._request_context.close_sse_stream:
1302+
if self._request_context and self._request_context.close_sse_stream: # pragma: no cover
13031303
await self._request_context.close_sse_stream()
13041304

13051305
# Convenience methods for common log levels

src/mcp/server/streamable_http.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ def is_terminated(self) -> bool:
186186
"""Check if this transport has been explicitly terminated."""
187187
return self._terminated
188188

189-
def close_sse_stream(self, request_id: RequestId) -> None:
189+
def close_sse_stream(self, request_id: RequestId) -> None: # pragma: no cover
190190
"""Close SSE connection for a specific request without terminating the stream.
191191
192192
This method closes the HTTP connection for the specified request, triggering
@@ -214,7 +214,7 @@ def close_sse_stream(self, request_id: RequestId) -> None:
214214
send_stream.close()
215215
receive_stream.close()
216216

217-
def _create_session_message(
217+
def _create_session_message( # pragma: no cover
218218
self,
219219
message: JSONRPCMessage,
220220
request: Request,
@@ -231,7 +231,7 @@ async def close_stream_callback() -> None:
231231
)
232232
return SessionMessage(message, metadata=metadata)
233233

234-
async def _send_priming_event(
234+
async def _send_priming_event( # pragma: no cover
235235
self,
236236
request_id: RequestId,
237237
sse_stream_writer: MemoryObjectSendStream[dict[str, Any]],

tests/shared/test_streamable_http.py

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,9 @@ def __init__(self):
8080
self._events: list[tuple[StreamId, EventId, types.JSONRPCMessage | None]] = []
8181
self._event_id_counter = 0
8282

83-
async def store_event(self, stream_id: StreamId, message: types.JSONRPCMessage | None) -> EventId:
83+
async def store_event( # pragma: no cover
84+
self, stream_id: StreamId, message: types.JSONRPCMessage | None
85+
) -> EventId:
8486
"""Store an event and return its ID."""
8587
self._event_id_counter += 1
8688
event_id = str(self._event_id_counter)
@@ -1817,10 +1819,10 @@ async def test_streamablehttp_client_auto_reconnects(
18171819
async def message_handler(
18181820
message: RequestResponder[types.ServerRequest, types.ClientResult] | types.ServerNotification | Exception,
18191821
) -> None:
1820-
if isinstance(message, Exception):
1821-
return
1822-
if isinstance(message, types.ServerNotification):
1823-
if isinstance(message.root, types.LoggingMessageNotification):
1822+
if isinstance(message, Exception): # pragma: no branch
1823+
return # pragma: no cover
1824+
if isinstance(message, types.ServerNotification): # pragma: no branch
1825+
if isinstance(message.root, types.LoggingMessageNotification): # pragma: no branch
18241826
captured_notifications.append(str(message.root.params.data))
18251827

18261828
async with streamablehttp_client(f"{server_url}/mcp") as (
@@ -1893,10 +1895,10 @@ async def test_streamablehttp_sse_polling_full_cycle(
18931895
async def message_handler(
18941896
message: RequestResponder[types.ServerRequest, types.ClientResult] | types.ServerNotification | Exception,
18951897
) -> None:
1896-
if isinstance(message, Exception):
1897-
return
1898-
if isinstance(message, types.ServerNotification):
1899-
if isinstance(message.root, types.LoggingMessageNotification):
1898+
if isinstance(message, Exception): # pragma: no branch
1899+
return # pragma: no cover
1900+
if isinstance(message, types.ServerNotification): # pragma: no branch
1901+
if isinstance(message.root, types.LoggingMessageNotification): # pragma: no branch
19001902
all_notifications.append(str(message.root.params.data))
19011903

19021904
async with streamablehttp_client(f"{server_url}/mcp") as (
@@ -1941,10 +1943,10 @@ async def test_streamablehttp_events_replayed_after_disconnect(
19411943
async def message_handler(
19421944
message: RequestResponder[types.ServerRequest, types.ClientResult] | types.ServerNotification | Exception,
19431945
) -> None:
1944-
if isinstance(message, Exception):
1945-
return
1946-
if isinstance(message, types.ServerNotification):
1947-
if isinstance(message.root, types.LoggingMessageNotification):
1946+
if isinstance(message, Exception): # pragma: no branch
1947+
return # pragma: no cover
1948+
if isinstance(message, types.ServerNotification): # pragma: no branch
1949+
if isinstance(message.root, types.LoggingMessageNotification): # pragma: no branch
19481950
notification_data.append(str(message.root.params.data))
19491951

19501952
async with streamablehttp_client(f"{server_url}/mcp") as (

uv.lock

Lines changed: 68 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)