带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
相关产品推荐
相关产品推荐

