You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

声明式HTTP客户端依赖注入的mypy类型提示问题

解决mypy类型不匹配错误的方案

要解决你遇到的默认值类型不匹配问题,同时保留类似FastAPI的声明方式,可通过泛型+工厂函数+类型转换的组合实现类型提示兼容:

步骤1:重构Dependency为泛型基类

首先将Dependency改为泛型类,关联目标类型T,让子类能绑定到参数注解的类型:

from typing import TypeVar, Generic, Any, Optional
import abc

T = TypeVar("T")
Empty = object()  # 假设你的Empty是类似的特殊标识值

class Dependency(Generic[T], abc.ABC):
    def __init__(
        self,
        default: Any = Empty,
        field_name: Optional[str] = None,
    ):
        self.default = default
        self._overridden_field_name = field_name

    @abc.abstractmethod
    def modify_request(self, request: "RawRequest") -> "RawRequest":
        raise NotImplementedError

步骤2:将Json改为内部实现类

把原来的Json类改为内部实现类_JsonImpl,继承泛型Dependency[T],保留原有功能逻辑:

class _JsonImpl(Dependency[T]):
    location = Location.json

    def __init__(self, default: Any = Empty):
        super().__init__(default=default)

    def modify_request(self, request: "RawRequest") -> "RawRequest":
        # 保留你的请求修改逻辑
        return request

步骤3:编写工厂函数Json

创建一个工厂函数Json,利用typing.cast让mypy将返回值推断为参数注解的类型,同时实际返回_JsonImpl实例:

from typing import cast

def Json(default: Any = Empty) -> T:
    """声明JSON类型的请求参数,兼容dict、Pydantic模型、dataclass等任意类型"""
    return cast(T, _JsonImpl(default))

用法保持不变

现在你依然可以用原来的方式声明函数,mypy会自动推断Json()的类型为参数注解的类型,不会再报错:

@http("GET", "/example")
def test_get(data: dict = Json()):
    ...

# 支持Pydantic模型示例
from pydantic import BaseModel
class User(BaseModel):
    name: str
    age: int

@http("POST", "/user")
def create_user(user: User = Json()):
    ...

原理说明

  • 泛型Dependency[T]让内部实现类绑定到参数注解的目标类型
  • 工厂函数Json通过cast(T)让mypy认为返回值是注解的类型,而实际运行时返回的是具备请求修改逻辑的_JsonImpl实例
  • 装饰器@http依然可以正常识别Dependency实例并执行modify_request逻辑,功能不受影响

内容的提问来源于stack exchange,提问作者floydya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 22:43:27