MyPy不允许将TypedDict类作为函数参数,是否为Bug?
问题原因说明
这个现象不是MyPy的Bug,属于MyPy对TypedDict的有意设计:
TypedDict是结构化类型(structural type),和普通标称类型的Python类不同,
type[A]/Type[A]的写法在MyPy的类型系统中不能正确匹配TypedDict的类对象本身。PyCharm的类型检查器对这类场景做了宽松适配,所以可以正常识别,二者的规则差异不属于MyPy的逻辑错误。
解决方法
方法1:用绑定TypedDict的TypeVar实现限定(推荐,无运行时开销,检查严格)
如果要严格限定仅能传入指定的A、B两个TypedDict类,可以这样写类型提示:
from typing import TypedDict, TypeVar class A(TypedDict): abc: str class B(TypedDict): xyz: str # 限定TypeVar的可选类型仅为A、B T = TypeVar('T', A, B) def func(dict_class: type[T]) -> None: print(dict_class.__annotations__) func(A) # MyPy检查通过 func(B) # MyPy检查通过 # 传入其他任意类/值都会触发MyPy报错
方法2:保留原有Union写法,添加局部忽略标记
如果不想修改原函数的类型提示,可以在调用处加单行忽略标记,仅忽略该参数的类型检查,不影响其他代码的类型校验:
func(A) # type: ignore[arg-type]
方法3:用cast强制类型转换
也可以在调用时通过cast明确告知MyPy类型,避免报错:
from typing import cast, Union func(cast(Union[type[A], type[B]], A))
内容的提问来源于stack exchange,提问作者Waszker
相关产品推荐
相关产品推荐

