2424import logging
2525from collections .abc import Awaitable , Callable , Mapping
2626from dataclasses import dataclass , field
27- from typing import Any , Generic , Literal , TypeVar , cast , overload
27+ from typing import Any , Generic , Literal , cast
2828
2929import anyio
3030import anyio .abc
3131from anyio .streams .memory import MemoryObjectReceiveStream , MemoryObjectSendStream
3232from opentelemetry .trace import SpanKind
3333from pydantic import ValidationError
34+ from typing_extensions import TypeVar
3435
3536from mcp .shared ._otel import inject_trace_context , otel_span
3637from mcp .shared ._stream_protocols import ReadStream , WriteStream
7071cancelled; without a bound, a wedged transport write would turn the shield
7172into an uncancellable hang (and block shutdown indefinitely)."""
7273
73- TransportT = TypeVar ("TransportT" , bound = TransportContext )
74+ TransportT = TypeVar ("TransportT" , bound = TransportContext , default = TransportContext )
7475
7576PeerCancelMode = Literal ["interrupt" , "signal" ]
7677"""How inbound `notifications/cancelled` is applied to a running handler.
@@ -236,29 +237,6 @@ class JSONRPCDispatcher(Dispatcher[TransportT]):
236237 conformance at the class definition rather than at first use.
237238 """
238239
239- @overload
240- def __init__ (
241- self : JSONRPCDispatcher [TransportContext ],
242- read_stream : ReadStream [SessionMessage | Exception ],
243- write_stream : WriteStream [SessionMessage ],
244- * ,
245- peer_cancel_mode : PeerCancelMode = "interrupt" ,
246- raise_handler_exceptions : bool = False ,
247- inline_methods : frozenset [str ] = frozenset (),
248- on_stream_exception : Callable [[Exception ], Awaitable [None ]] | None = None ,
249- ) -> None : ...
250- @overload
251- def __init__ (
252- self ,
253- read_stream : ReadStream [SessionMessage | Exception ],
254- write_stream : WriteStream [SessionMessage ],
255- * ,
256- transport_builder : Callable [[MessageMetadata ], TransportT ],
257- peer_cancel_mode : PeerCancelMode = "interrupt" ,
258- raise_handler_exceptions : bool = False ,
259- inline_methods : frozenset [str ] = frozenset (),
260- on_stream_exception : Callable [[Exception ], Awaitable [None ]] | None = None ,
261- ) -> None : ...
262240 def __init__ (
263241 self ,
264242 read_stream : ReadStream [SessionMessage | Exception ],
@@ -272,9 +250,9 @@ def __init__(
272250 ) -> None :
273251 self ._read_stream = read_stream
274252 self ._write_stream = write_stream
275- # The overloads guarantee that when `transport_builder` is omitted,
276- # `TransportT` is `TransportContext`, so the default is type-correct;
277- # pyright can't see across overloads , hence the cast.
253+ # When `transport_builder` is omitted, `TransportT` falls back to its
254+ # default ( `TransportContext`) , so the default builder is type-correct;
255+ # pyright can't connect the two , hence the cast.
278256 self ._transport_builder = cast (
279257 "Callable[[MessageMetadata], TransportT]" ,
280258 transport_builder or _default_transport_builder ,
0 commit comments