Skip to content

Commit 7ba5ec0

Browse files
committed
test: drop type-ignores — use InMemoryTransport + assert-isinstance narrowing
InMemoryTransport handles the _lowlevel_server unwrap internally, so the test no longer reaches for it. The union-attr on CallToolResult.content is narrowed with a proper assert isinstance(content, TextContent).
1 parent 8c1556b commit 7ba5ec0

File tree

1 file changed

+10
-18
lines changed

1 file changed

+10
-18
lines changed

tests/shared/test_dispatcher.py

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44

55
from typing import Any
66

7-
import anyio
87
import pytest
98

9+
from mcp.client._memory import InMemoryTransport
1010
from mcp.client.session import ClientSession
1111
from mcp.server.mcpserver import Context, MCPServer
1212
from mcp.shared._context import RequestContext
@@ -16,7 +16,6 @@
1616
OnNotificationFn,
1717
OnRequestFn,
1818
)
19-
from mcp.shared.memory import create_client_server_memory_streams
2019
from mcp.shared.message import MessageMetadata
2120
from mcp.types import (
2221
CreateMessageRequestParams,
@@ -96,25 +95,18 @@ async def sampling_callback(
9695
stop_reason="endTurn",
9796
)
9897

99-
async with create_client_server_memory_streams() as (client_streams, server_streams):
100-
client_read, client_write = client_streams
101-
server_read, server_write = server_streams
102-
103-
# The spy wraps a real JSON-RPC dispatcher so the server side works unchanged.
104-
# What matters is that ClientSession has no idea it isn't the default.
98+
# InMemoryTransport runs the server for us and yields client-side streams —
99+
# we intercept those streams and feed them through a custom dispatcher.
100+
async with InMemoryTransport(app) as (client_read, client_write):
105101
inner = JSONRPCDispatcher(client_read, client_write, response_routers=[])
106102
spy = SpyDispatcher(inner)
107103

108-
async with anyio.create_task_group() as tg:
109-
server = app._lowlevel_server # type: ignore[reportPrivateUsage]
110-
tg.start_soon(lambda: server.run(server_read, server_write, server.create_initialization_options()))
111-
112-
async with ClientSession(dispatcher=spy, sampling_callback=sampling_callback) as session:
113-
await session.initialize()
114-
result = await session.call_tool("ask", {"question": "meaning of life?"})
115-
assert result.content[0].text == "42" # type: ignore[union-attr]
116-
117-
tg.cancel_scope.cancel()
104+
async with ClientSession(dispatcher=spy, sampling_callback=sampling_callback) as session:
105+
await session.initialize()
106+
result = await session.call_tool("ask", {"question": "meaning of life?"})
107+
content = result.content[0]
108+
assert isinstance(content, TextContent)
109+
assert content.text == "42"
118110

119111
# initialize, tools/call (triggers sampling on the server), tools/list (schema refresh)
120112
assert [r["method"] for r in spy.sent_requests] == ["initialize", "tools/call", "tools/list"]

0 commit comments

Comments
 (0)