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

带bound约束的TypeVar参数设默认值时Mypy报错,如何正确注解?

带bound约束的TypeVar与默认参数的类型注解问题

当使用带bound约束的TypeVar注解函数参数并设置默认值时,即便默认值符合该TypeVar的约束范围,Mypy仍会报错提示默认值类型与参数类型不兼容,尽管调用函数时类型推断的结果是完全正确的。

问题示例代码

class A:
    pass

class B(A):
    pass

Instance = TypeVar("Instance", bound=A)

def get_instance(cls: type[Instance] = A) -> Instance:
    return cls()

Mypy报错信息

运行Mypy会抛出如下类型错误:

error: Incompatible default for argument "cls" (default has type "Type[A]", argument has type "Type[Instance]")

调用时的类型推断结果

但直接调用函数时,reveal_type的输出完全符合预期:

instance_a = get_instance(cls=A)
reveal_type(instance_a)  # note: Revealed type is "A"

instance_b = get_instance(cls=B)
reveal_type(instance_b)  # note: Revealed type is "B"

解决方案

方案1:使用cast进行类型断言

通过typing.cast告诉Mypy,默认值A的类型符合type[Instance]的约束,这是最简洁的处理方式:

from typing import TypeVar, cast

class A:
    pass

class B(A):
    pass

Instance = TypeVar("Instance", bound=A)

def get_instance(cls: type[Instance] = cast(type[Instance], A)) -> Instance:
    return cls()

方案2:使用函数重载明确场景

通过@overload定义两种调用场景(指定子类、使用默认值),让类型推断更精准:

from typing import TypeVar, overload

class A:
    pass

class B(A):
    pass

Instance = TypeVar("Instance", bound=A)

@overload
def get_instance(cls: type[Instance]) -> Instance:
    ...

@overload
def get_instance() -> A:
    ...

def get_instance(cls: type[A] = A) -> A:
    return cls()

方案3:使用Union兼容两种类型

将参数类型注解为type[Instance]和type[A]的联合类型,兼顾简洁性与类型安全:

from typing import TypeVar, Union

class A:
    pass

class B(A):
    pass

Instance = TypeVar("Instance", bound=A)

def get_instance(cls: Union[type[Instance], type[A]] = A) -> Instance:
    return cls()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 08:47:23