mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-28 02:10:38 +02:00
Remove invalid-argument-type ignore and fix type errors (#1588)
Co-authored-by: Jeremiah Lowin <jlowin@users.noreply.github.com> Co-authored-by: marvin-context-protocol[bot] <225465937+marvin-context-protocol[bot]@users.noreply.github.com>
This commit is contained in:
parent
c730aaa6b0
commit
302eb9c3f5
15 changed files with 54 additions and 41 deletions
|
|
@ -124,7 +124,6 @@ python-version = "3.10"
|
|||
|
||||
[tool.ty.rules]
|
||||
# Rules with too many errors to fix right now (40+ each)
|
||||
invalid-argument-type = "ignore" # 40 errors
|
||||
no-matching-overload = "ignore" # 126 errors
|
||||
unknown-argument = "ignore" # 61 errors
|
||||
unresolved-attribute = "ignore" # 60 errors
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ def version(
|
|||
cyclopts.Parameter(
|
||||
"--copy",
|
||||
help="Copy version information to clipboard",
|
||||
negative=False,
|
||||
negative="",
|
||||
),
|
||||
] = False,
|
||||
):
|
||||
|
|
@ -153,7 +153,7 @@ async def dev(
|
|||
cyclopts.Parameter(
|
||||
"--with",
|
||||
help="Additional packages to install",
|
||||
negative=False,
|
||||
negative="",
|
||||
),
|
||||
] = [],
|
||||
inspector_version: Annotated[
|
||||
|
|
@ -385,7 +385,7 @@ async def run(
|
|||
cyclopts.Parameter(
|
||||
"--no-banner",
|
||||
help="Don't show the server banner",
|
||||
negative=False,
|
||||
negative="",
|
||||
),
|
||||
] = False,
|
||||
python: Annotated[
|
||||
|
|
@ -400,7 +400,7 @@ async def run(
|
|||
cyclopts.Parameter(
|
||||
"--with",
|
||||
help="Additional packages to install (can be used multiple times)",
|
||||
negative=False,
|
||||
negative="",
|
||||
),
|
||||
] = [],
|
||||
project: Annotated[
|
||||
|
|
@ -586,7 +586,7 @@ async def inspect(
|
|||
cyclopts.Parameter(
|
||||
"--with",
|
||||
help="Additional packages to install (can be used multiple times)",
|
||||
negative=False,
|
||||
negative="",
|
||||
),
|
||||
] = [],
|
||||
project: Annotated[
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@ async def claude_code_command(
|
|||
cyclopts.Parameter(
|
||||
"--with",
|
||||
help="Additional packages to install",
|
||||
negative=False,
|
||||
negative="",
|
||||
),
|
||||
] = [],
|
||||
env_vars: Annotated[
|
||||
|
|
@ -197,7 +197,7 @@ async def claude_code_command(
|
|||
cyclopts.Parameter(
|
||||
"--env",
|
||||
help="Environment variables in KEY=VALUE format",
|
||||
negative=False,
|
||||
negative="",
|
||||
),
|
||||
] = [],
|
||||
env_file: Annotated[
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ async def claude_desktop_command(
|
|||
cyclopts.Parameter(
|
||||
"--with",
|
||||
help="Additional packages to install",
|
||||
negative=False,
|
||||
negative="",
|
||||
),
|
||||
] = [],
|
||||
env_vars: Annotated[
|
||||
|
|
@ -170,7 +170,7 @@ async def claude_desktop_command(
|
|||
cyclopts.Parameter(
|
||||
"--env",
|
||||
help="Environment variables in KEY=VALUE format",
|
||||
negative=False,
|
||||
negative="",
|
||||
),
|
||||
] = [],
|
||||
env_file: Annotated[
|
||||
|
|
|
|||
|
|
@ -289,7 +289,7 @@ async def cursor_command(
|
|||
cyclopts.Parameter(
|
||||
"--with",
|
||||
help="Additional packages to install",
|
||||
negative=False,
|
||||
negative="",
|
||||
),
|
||||
] = [],
|
||||
env_vars: Annotated[
|
||||
|
|
@ -297,7 +297,7 @@ async def cursor_command(
|
|||
cyclopts.Parameter(
|
||||
"--env",
|
||||
help="Environment variables in KEY=VALUE format",
|
||||
negative=False,
|
||||
negative="",
|
||||
),
|
||||
] = [],
|
||||
env_file: Annotated[
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ async def mcp_json_command(
|
|||
cyclopts.Parameter(
|
||||
"--with",
|
||||
help="Additional packages to install",
|
||||
negative=False,
|
||||
negative="",
|
||||
),
|
||||
] = [],
|
||||
env_vars: Annotated[
|
||||
|
|
@ -143,7 +143,7 @@ async def mcp_json_command(
|
|||
cyclopts.Parameter(
|
||||
"--env",
|
||||
help="Environment variables in KEY=VALUE format",
|
||||
negative=False,
|
||||
negative="",
|
||||
),
|
||||
] = [],
|
||||
env_file: Annotated[
|
||||
|
|
@ -158,7 +158,7 @@ async def mcp_json_command(
|
|||
cyclopts.Parameter(
|
||||
"--copy",
|
||||
help="Copy configuration to clipboard instead of printing to stdout",
|
||||
negative=False,
|
||||
negative="",
|
||||
),
|
||||
] = False,
|
||||
python: Annotated[
|
||||
|
|
|
|||
|
|
@ -86,8 +86,8 @@ async def import_server(file: Path, server_or_factory: str | None = None) -> Any
|
|||
logger.error("Could not load module", extra={"file": str(file)})
|
||||
sys.exit(1)
|
||||
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(module)
|
||||
module = importlib.util.module_from_spec(spec) # type: ignore[arg-type]
|
||||
spec.loader.exec_module(module) # type: ignore[union-attr]
|
||||
|
||||
# If no object specified, try common server names
|
||||
if not server_or_factory:
|
||||
|
|
@ -129,7 +129,7 @@ async def import_server(file: Path, server_or_factory: str | None = None) -> Any
|
|||
)
|
||||
sys.exit(1)
|
||||
|
||||
return await _resolve_server_or_factory(obj, file, server_or_factory)
|
||||
return await _resolve_server_or_factory(obj, file, server_or_factory) # type: ignore[arg-type]
|
||||
|
||||
|
||||
async def _resolve_server_or_factory(obj: Any, file: Path, name: str) -> Any:
|
||||
|
|
|
|||
|
|
@ -217,8 +217,13 @@ class OAuth(OAuthClientProvider):
|
|||
self.redirect_port = callback_port or find_available_port()
|
||||
redirect_uri = f"http://localhost:{self.redirect_port}/callback"
|
||||
|
||||
scopes_str: str
|
||||
if isinstance(scopes, list):
|
||||
scopes = " ".join(scopes)
|
||||
scopes_str = " ".join(scopes)
|
||||
elif scopes is not None:
|
||||
scopes_str = str(scopes)
|
||||
else:
|
||||
scopes_str = ""
|
||||
|
||||
client_metadata = OAuthClientMetadata(
|
||||
client_name=client_name,
|
||||
|
|
@ -226,7 +231,7 @@ class OAuth(OAuthClientProvider):
|
|||
grant_types=["authorization_code", "refresh_token"],
|
||||
response_types=["code"],
|
||||
# token_endpoint_auth_method="client_secret_post",
|
||||
scope=scopes,
|
||||
scope=scopes_str,
|
||||
**(additional_client_metadata or {}),
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -236,7 +236,7 @@ class Client(Generic[ClientTransportT]):
|
|||
self._progress_handler = progress_handler
|
||||
|
||||
if isinstance(timeout, int | float):
|
||||
timeout = datetime.timedelta(seconds=timeout)
|
||||
timeout = datetime.timedelta(seconds=float(timeout))
|
||||
|
||||
# handle init handshake timeout
|
||||
if init_timeout is None:
|
||||
|
|
@ -819,7 +819,7 @@ class Client(Generic[ClientTransportT]):
|
|||
"""
|
||||
|
||||
if isinstance(timeout, int | float):
|
||||
timeout = datetime.timedelta(seconds=timeout)
|
||||
timeout = datetime.timedelta(seconds=float(timeout))
|
||||
result = await self.session.call_tool(
|
||||
name=name,
|
||||
arguments=arguments,
|
||||
|
|
|
|||
|
|
@ -182,7 +182,7 @@ class SSETransport(ClientTransport):
|
|||
self.httpx_client_factory = httpx_client_factory
|
||||
|
||||
if isinstance(sse_read_timeout, int | float):
|
||||
sse_read_timeout = datetime.timedelta(seconds=sse_read_timeout)
|
||||
sse_read_timeout = datetime.timedelta(seconds=float(sse_read_timeout))
|
||||
self.sse_read_timeout = sse_read_timeout
|
||||
|
||||
def _set_auth(self, auth: httpx.Auth | Literal["oauth"] | str | None):
|
||||
|
|
@ -252,7 +252,7 @@ class StreamableHttpTransport(ClientTransport):
|
|||
self.httpx_client_factory = httpx_client_factory
|
||||
|
||||
if isinstance(sse_read_timeout, int | float):
|
||||
sse_read_timeout = datetime.timedelta(seconds=sse_read_timeout)
|
||||
sse_read_timeout = datetime.timedelta(seconds=float(sse_read_timeout))
|
||||
self.sse_read_timeout = sse_read_timeout
|
||||
|
||||
def _set_auth(self, auth: httpx.Auth | Literal["oauth"] | str | None):
|
||||
|
|
@ -1024,28 +1024,36 @@ def infer_transport(
|
|||
|
||||
# the transport is a FastMCP server (2.x or 1.0)
|
||||
elif isinstance(transport, FastMCP | FastMCP1Server):
|
||||
inferred_transport = FastMCPTransport(mcp=transport)
|
||||
inferred_transport = FastMCPTransport(
|
||||
mcp=cast(FastMCP[Any] | FastMCP1Server, transport)
|
||||
)
|
||||
|
||||
# the transport is a path to a script
|
||||
elif isinstance(transport, Path | str) and Path(transport).exists():
|
||||
if str(transport).endswith(".py"):
|
||||
inferred_transport = PythonStdioTransport(script_path=transport)
|
||||
inferred_transport = PythonStdioTransport(script_path=cast(Path, transport))
|
||||
elif str(transport).endswith(".js"):
|
||||
inferred_transport = NodeStdioTransport(script_path=transport)
|
||||
inferred_transport = NodeStdioTransport(script_path=cast(Path, transport))
|
||||
else:
|
||||
raise ValueError(f"Unsupported script type: {transport}")
|
||||
|
||||
# the transport is an http(s) URL
|
||||
elif isinstance(transport, AnyUrl | str) and str(transport).startswith("http"):
|
||||
inferred_transport_type = infer_transport_type_from_url(transport)
|
||||
inferred_transport_type = infer_transport_type_from_url(
|
||||
cast(AnyUrl | str, transport)
|
||||
)
|
||||
if inferred_transport_type == "sse":
|
||||
inferred_transport = SSETransport(url=transport)
|
||||
inferred_transport = SSETransport(url=cast(AnyUrl | str, transport))
|
||||
else:
|
||||
inferred_transport = StreamableHttpTransport(url=transport)
|
||||
inferred_transport = StreamableHttpTransport(
|
||||
url=cast(AnyUrl | str, transport)
|
||||
)
|
||||
|
||||
# if the transport is a config dict or MCPConfig
|
||||
elif isinstance(transport, dict | MCPConfig):
|
||||
inferred_transport = MCPConfigTransport(config=transport)
|
||||
inferred_transport = MCPConfigTransport(
|
||||
config=cast(dict | MCPConfig, transport)
|
||||
)
|
||||
|
||||
# the transport is an unknown type
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -548,7 +548,7 @@ class Context:
|
|||
if isinstance(validated_data, ScalarElicitationType):
|
||||
return AcceptedElicitation[T](data=validated_data.value)
|
||||
else:
|
||||
return AcceptedElicitation[T](data=validated_data)
|
||||
return AcceptedElicitation[T](data=cast(T, validated_data))
|
||||
elif result.content:
|
||||
raise ValueError(
|
||||
"Elicitation expected an empty response, but received: "
|
||||
|
|
|
|||
|
|
@ -1027,7 +1027,7 @@ class FastMCP(Generic[LifespanResultT]):
|
|||
description=description,
|
||||
tags=tags,
|
||||
output_schema=output_schema,
|
||||
annotations=annotations,
|
||||
annotations=cast(ToolAnnotations | None, annotations),
|
||||
exclude_args=exclude_args,
|
||||
meta=meta,
|
||||
serializer=self._tool_serializer,
|
||||
|
|
@ -1257,7 +1257,7 @@ class FastMCP(Generic[LifespanResultT]):
|
|||
mime_type=mime_type,
|
||||
tags=tags,
|
||||
enabled=enabled,
|
||||
annotations=annotations,
|
||||
annotations=cast(Annotations | None, annotations),
|
||||
meta=meta,
|
||||
)
|
||||
self.add_template(template)
|
||||
|
|
@ -1272,7 +1272,7 @@ class FastMCP(Generic[LifespanResultT]):
|
|||
mime_type=mime_type,
|
||||
tags=tags,
|
||||
enabled=enabled,
|
||||
annotations=annotations,
|
||||
annotations=cast(Annotations | None, annotations),
|
||||
meta=meta,
|
||||
)
|
||||
self.add_resource(resource)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ from __future__ import annotations
|
|||
|
||||
import importlib.metadata
|
||||
from dataclasses import dataclass
|
||||
from typing import Any
|
||||
from typing import Any, cast
|
||||
|
||||
from mcp.server.fastmcp import FastMCP as FastMCP1x
|
||||
|
||||
|
|
@ -318,4 +318,4 @@ async def inspect_fastmcp(mcp: FastMCP[Any] | FastMCP1x) -> FastMCPInfo:
|
|||
if isinstance(mcp, FastMCP1x):
|
||||
return await inspect_fastmcp_v1(mcp)
|
||||
else:
|
||||
return await inspect_fastmcp_v2(mcp)
|
||||
return await inspect_fastmcp_v2(cast(FastMCP[Any], mcp))
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ from pathlib import Path
|
|||
from types import EllipsisType, UnionType
|
||||
from typing import (
|
||||
Annotated,
|
||||
Any,
|
||||
Protocol,
|
||||
TypeAlias,
|
||||
TypeVar,
|
||||
|
|
@ -122,7 +123,7 @@ def issubclass_safe(cls: type, base: type) -> bool:
|
|||
return False
|
||||
|
||||
|
||||
def is_class_member_of_type(cls: type, base: type) -> bool:
|
||||
def is_class_member_of_type(cls: Any, base: type) -> bool:
|
||||
"""
|
||||
Check if cls is a member of base, even if cls is a type variable.
|
||||
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ class TestParseModelPreferences:
|
|||
|
||||
def test_parse_model_preferences_invalid_type(self, context):
|
||||
with pytest.raises(ValueError):
|
||||
_parse_model_preferences(model_preferences=123) # pyright: ignore[reportArgumentType]
|
||||
_parse_model_preferences(model_preferences=123) # pyright: ignore[reportArgumentType] # type: ignore[invalid-argument-type]
|
||||
|
||||
|
||||
class TestSessionId:
|
||||
|
|
@ -97,7 +97,7 @@ class TestSessionId:
|
|||
mock_headers = {"mcp-session-id": "test-session-123"}
|
||||
|
||||
token = request_ctx.set(
|
||||
RequestContext(
|
||||
RequestContext( # type: ignore[arg-type]
|
||||
request_id=0,
|
||||
meta=None,
|
||||
session=MagicMock(wraps={}),
|
||||
|
|
@ -118,7 +118,7 @@ class TestSessionId:
|
|||
from mcp.shared.context import RequestContext
|
||||
|
||||
token = request_ctx.set(
|
||||
RequestContext(
|
||||
RequestContext( # type: ignore[arg-type]
|
||||
request_id=0,
|
||||
meta=None,
|
||||
session=MagicMock(wraps={}),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue