22import types
33import inspect
44import traceback
5- from typing import Any , Callable , get_type_hints , get_origin , get_args , Union , TypedDict , TypeAlias , NotRequired
5+ from typing import Any , Callable , get_type_hints , get_origin , get_args , Union , TypedDict , TypeAlias , NotRequired , is_typeddict
66
77JsonRpcId : TypeAlias = str | int | float | None
88JsonRpcParams : TypeAlias = dict [str , Any ] | list [Any ] | None
@@ -168,6 +168,10 @@ def _call(self, method: str, params: Any) -> Any:
168168 arg_origin = get_origin (arg_type )
169169 check_type = arg_origin if arg_origin is not None else arg_type
170170
171+ # TypedDict cannot be used with isinstance - check for dict instead
172+ if is_typeddict (arg_type ):
173+ check_type = dict
174+
171175 if isinstance (value , check_type ):
172176 type_matched = True
173177 break
@@ -187,6 +191,16 @@ def _call(self, method: str, params: Any) -> Any:
187191 validated_params [param_name ] = value
188192 continue
189193
194+ # Handle TypedDict (must check before basic types)
195+ if is_typeddict (expected_type ):
196+ if not isinstance (value , dict ):
197+ raise JsonRpcException (
198+ - 32602 ,
199+ f"Invalid params: { param_name } expected dict, got { type (value ).__name__ } "
200+ )
201+ validated_params [param_name ] = value
202+ continue
203+
190204 # Handle basic types
191205 if isinstance (expected_type , type ):
192206 # Allow int -> float conversion
0 commit comments