fix: 修复 mypy 类型检查错误并升级到 Python 3.14

主要变更:
- 修复 1483 个 mypy 类型检查错误
- 添加缺失的类型注解 (Any, Callable, Session 等)
- 修复隐式 Optional 类型 (param: Type = None -> param: Type | None = None)
- 修复 __new__ 单例模式返回类型
- 添加 type: ignore 注释处理第三方库类型问题
- 更新 pyproject.toml 依赖到 Python 3.14 兼容版本
- 更新 mypy/black 配置为 Python 3.14
This commit is contained in:
fawney19
2026-01-30 14:30:57 +08:00
parent 7066166757
commit 5603c72f40
142 changed files with 2864 additions and 1853 deletions

View File

@@ -88,7 +88,7 @@ _LAZY_IMPORTS = {
}
def __getattr__(name: str):
def __getattr__(name: str) -> None:
"""延迟导入以避免循环依赖"""
if name in _LAZY_IMPORTS:
module_path, attr_name = _LAZY_IMPORTS[name]

View File

@@ -18,6 +18,7 @@ Chat Adapter 通用基类
from __future__ import annotations
from sqlalchemy.orm import Session
import time
import traceback
from abc import abstractmethod
@@ -129,7 +130,7 @@ class ChatAdapterBase(ApiAdapter):
def __init__(self, allowed_api_formats: list[str] | None = None):
self.allowed_api_formats = allowed_api_formats or [self.FORMAT_ID]
async def handle(self, context: ApiRequestContext):
async def handle(self, context: ApiRequestContext) -> Any:
"""处理 Chat API 请求"""
http_request = context.request
user = context.user
@@ -262,14 +263,14 @@ class ChatAdapterBase(ApiAdapter):
def _create_handler(
self,
*,
db,
user,
api_key,
db: Session,
user: Any,
api_key: Any,
request_id: str,
client_ip: str,
user_agent: str,
start_time: float,
):
) -> Any:
"""创建 Handler 实例 - 子类可覆盖"""
return self.HANDLER_CLASS(
db=db,
@@ -305,7 +306,7 @@ class ChatAdapterBase(ApiAdapter):
return merged
@abstractmethod
def _validate_request_body(self, original_request_body: dict, path_params: dict = None):
def _validate_request_body(self, original_request_body: dict, path_params: dict | None = None) -> None:
"""
验证请求体 - 子类必须实现
@@ -318,7 +319,7 @@ class ChatAdapterBase(ApiAdapter):
"""
pass
def _extract_message_count(self, payload: dict[str, Any], request_obj) -> int:
def _extract_message_count(self, payload: dict[str, Any], request_obj: Any) -> int:
"""
提取消息数量 - 子类可覆盖
@@ -329,7 +330,7 @@ class ChatAdapterBase(ApiAdapter):
messages = request_obj.messages
return len(messages) if isinstance(messages, list) else 0
def _build_audit_metadata(self, payload: dict[str, Any], request_obj) -> dict[str, Any]:
def _build_audit_metadata(self, payload: dict[str, Any], request_obj: Any) -> dict[str, Any]:
"""
构建审计日志元数据 - 子类可覆盖
"""
@@ -351,9 +352,9 @@ class ChatAdapterBase(ApiAdapter):
self,
e: Exception,
*,
db,
user,
api_key,
db: Session,
user: Any,
api_key: Any,
model: str,
stream: bool,
start_time: float,
@@ -422,9 +423,9 @@ class ChatAdapterBase(ApiAdapter):
self,
e: Exception,
*,
db,
user,
api_key,
db: Session,
user: Any,
api_key: Any,
model: str,
stream: bool,
start_time: float,
@@ -710,7 +711,7 @@ def register_adapter(adapter_class: type[ChatAdapterBase]) -> type[ChatAdapterBa
return adapter_class
def _ensure_adapters_loaded():
def _ensure_adapters_loaded() -> None:
"""确保所有 Adapter 已被加载(触发注册)"""
global _ADAPTERS_LOADED
if _ADAPTERS_LOADED:

View File

@@ -19,6 +19,8 @@ Chat Handler Base - Chat API 格式的通用基类
- StreamTelemetryRecorder: 统计记录Usage、Audit、Candidate
"""
from __future__ import annotations
import asyncio
import json
from abc import ABC, abstractmethod

View File

@@ -15,12 +15,15 @@ CLI Adapter 通用基类
- 可选覆盖 compute_total_input_context() 自定义总输入上下文计算
"""
from __future__ import annotations
import time
import traceback
from typing import Any
import httpx
from fastapi import HTTPException, Request
from sqlalchemy.orm import Session
from fastapi.responses import JSONResponse
from src.api.base.adapter import ApiAdapter, ApiMode
@@ -124,7 +127,7 @@ class CliAdapterBase(ApiAdapter):
"""
return get_adapter_protected_keys(cls._get_api_format())
async def handle(self, context: ApiRequestContext):
async def handle(self, context: ApiRequestContext) -> Any:
"""处理 CLI API 请求"""
http_request = context.request
user = context.user
@@ -332,9 +335,9 @@ class CliAdapterBase(ApiAdapter):
self,
e: Exception,
*,
db,
user,
api_key,
db: Session,
user: Any,
api_key: Any,
model: str,
stream: bool,
start_time: float,
@@ -403,9 +406,9 @@ class CliAdapterBase(ApiAdapter):
self,
e: Exception,
*,
db,
user,
api_key,
db: Session,
user: Any,
api_key: Any,
model: str,
stream: bool,
start_time: float,
@@ -748,7 +751,7 @@ def register_cli_adapter(adapter_class: type[CliAdapterBase]) -> type[CliAdapter
return adapter_class
def _ensure_cli_adapters_loaded():
def _ensure_cli_adapters_loaded() -> None:
"""确保所有 CLI Adapter 已被加载(触发注册)"""
global _CLI_ADAPTERS_LOADED
if _CLI_ADAPTERS_LOADED:

View File

@@ -9,6 +9,8 @@
5. 流式平滑输出
"""
from __future__ import annotations
import asyncio
import codecs
import json

View File

@@ -4,6 +4,8 @@ Claude Chat Adapter - 基于 ChatAdapterBase 的 Claude Chat API 适配器
处理 /v1/messages 端点的 Claude Chat 格式请求。
"""
from __future__ import annotations
from typing import Any
import httpx
@@ -96,7 +98,7 @@ class ClaudeChatAdapter(ChatAdapterBase):
"""
return input_tokens + cache_creation_input_tokens + cache_read_input_tokens
def _validate_request_body(self, original_request_body: dict, path_params: dict = None):
def _validate_request_body(self, original_request_body: dict, path_params: dict | None = None) -> None:
"""验证请求体"""
try:
if not isinstance(original_request_body, dict):
@@ -124,7 +126,7 @@ class ClaudeChatAdapter(ChatAdapterBase):
)
return request
def _build_audit_metadata(self, _payload: dict[str, Any], request_obj) -> dict[str, Any]:
def _build_audit_metadata(self, _payload: dict[str, Any], request_obj: Any) -> dict[str, Any]:
"""构建 Claude Chat 特定的审计元数据"""
role_counts: dict[str, int] = {}
for message in request_obj.messages:
@@ -201,7 +203,7 @@ class ClaudeChatAdapter(ChatAdapterBase):
# build_request_body 使用基类实现,通过 format_conversion_registry 自动转换 OPENAI -> CLAUDE
def build_claude_adapter(x_app_header: str | None):
def build_claude_adapter(x_app_header: str | None) -> Any:
"""根据 x-app 头部构造 Chat 或 Claude Code 适配器。"""
if x_app_header and x_app_header.lower() == "cli":
from src.api.handlers.claude_cli.adapter import ClaudeCliAdapter
@@ -228,7 +230,7 @@ class ClaudeTokenCountAdapter(ApiAdapter):
return authorization.replace("Bearer ", "")
return None
async def handle(self, context: ApiRequestContext):
async def handle(self, context: ApiRequestContext) -> Any:
payload = context.ensure_json_body()
try:

View File

@@ -4,6 +4,8 @@ Claude CLI Adapter - 基于通用 CLI Adapter 基类的简化实现
继承 CliAdapterBase只需配置 FORMAT_ID 和 HANDLER_CLASS。
"""
from __future__ import annotations
from typing import Any
import httpx

View File

@@ -91,7 +91,7 @@ class GeminiChatAdapter(ChatAdapterBase):
"""
return original_request_body.copy()
def _validate_request_body(self, original_request_body: dict, path_params: dict = None):
def _validate_request_body(self, original_request_body: dict, path_params: dict | None = None) -> None:
"""验证请求体"""
path_params = path_params or {}
is_stream = path_params.get("stream", False)
@@ -124,14 +124,14 @@ class GeminiChatAdapter(ChatAdapterBase):
request.stream = is_stream
return request
def _extract_message_count(self, payload: dict[str, Any], request_obj) -> int:
def _extract_message_count(self, payload: dict[str, Any], request_obj: Any) -> int:
"""提取消息数量"""
contents = payload.get("contents", [])
if hasattr(request_obj, "contents"):
contents = request_obj.contents
return len(contents) if isinstance(contents, list) else 0
def _build_audit_metadata(self, payload: dict[str, Any], request_obj) -> dict[str, Any]:
def _build_audit_metadata(self, payload: dict[str, Any], request_obj: Any) -> dict[str, Any]:
"""构建 Gemini Chat 特定的审计元数据"""
role_counts: dict[str, int] = {}

View File

@@ -6,6 +6,7 @@ Gemini Chat Handler
from __future__ import annotations
from starlette.requests import Request
from typing import Any
from src.api.handlers.base.chat_handler_base import ChatHandlerBase
@@ -102,7 +103,7 @@ class GeminiChatHandler(ChatHandlerBase):
return str(path_params["model"])
return "unknown"
async def _convert_request(self, request):
async def _convert_request(self, request: Request) -> None:
"""
将请求转换为 Gemini 格式的 Pydantic 对象

View File

@@ -4,6 +4,8 @@ Gemini CLI Adapter - 基于通用 CLI Adapter 基类的实现
继承 CliAdapterBase处理 Gemini CLI 格式的请求。
"""
from __future__ import annotations
from typing import Any
import httpx

View File

@@ -4,6 +4,8 @@ OpenAI Chat Adapter - 基于 ChatAdapterBase 的 OpenAI Chat API 适配器
处理 /v1/chat/completions 端点的 OpenAI Chat 格式请求。
"""
from __future__ import annotations
from typing import Any
import httpx
@@ -37,7 +39,7 @@ class OpenAIChatAdapter(ChatAdapterBase):
def __init__(self, allowed_api_formats: list[str] | None = None):
super().__init__(allowed_api_formats or ["OPENAI"])
def _validate_request_body(self, original_request_body: dict, path_params: dict = None):
def _validate_request_body(self, original_request_body: dict, path_params: dict | None = None) -> None:
"""验证请求体"""
if not isinstance(original_request_body, dict):
return self._error_response(
@@ -66,7 +68,7 @@ class OpenAIChatAdapter(ChatAdapterBase):
max_tokens=original_request_body.get("max_tokens"),
)
def _build_audit_metadata(self, payload: dict[str, Any], request_obj) -> dict[str, Any]:
def _build_audit_metadata(self, payload: dict[str, Any], request_obj: Any) -> dict[str, Any]:
"""构建 OpenAI Chat 特定的审计元数据"""
role_counts = {}
for message in request_obj.messages:

View File

@@ -5,6 +5,9 @@ OpenAI Chat Handler - 基于通用 Chat Handler 基类的简化实现
代码量从原来的 ~1315 行减少到 ~100 行。
"""
from __future__ import annotations
from starlette.requests import Request
from typing import Any
from src.api.handlers.base.chat_handler_base import ChatHandlerBase
@@ -63,7 +66,7 @@ class OpenAIChatHandler(ChatHandlerBase):
result["model"] = mapped_model
return result
async def _convert_request(self, request):
async def _convert_request(self, request: Request) -> None:
"""
将请求转换为 OpenAI 格式的 Pydantic 对象

View File

@@ -4,6 +4,8 @@ OpenAI CLI Adapter - 基于通用 CLI Adapter 基类的简化实现
继承 CliAdapterBase只需配置 FORMAT_ID 和 HANDLER_CLASS。
"""
from __future__ import annotations
from typing import Any
import httpx