实例化含泛型元组的类时出现Pylance类型分配错误
Pylance逆变泛型类型匹配异常问题
问题代码
from typing import Generic, Tuple, TypeVar Type = TypeVar("Type", contravariant=True) class Interface(Generic[Type]): pass SpecType = TypeVar("SpecType") class Implementation(Interface[Tuple[str, SpecType]], Generic[SpecType]): pass a: Interface[Tuple[str, float]] = Implementation[float]()
Pylance报错信息
Expression of type "Implementation[float]" cannot be assigned to declared type "Interface[Tuple[str, float]]"
"Implementation[float]" is incompatible with "Interface[Tuple[str, float]]"
TypeVar "Type@Interface" is contravariant
"Tuple[str, SpecType@Implementation]" is incompatible with "Tuple[str, float]"
Tuple entry 2 is incorrect type
"object*" is incompatible with "float"
问题分析
- 逻辑矛盾:明明已经显式传入
float作为Implementation的SpecType泛型参数,但错误提示却判定SpecType@Implementation的实际类型是object*。按照类的继承关系,Implementation[float]应该完全符合Interface[Tuple[str, float]]的类型要求,不该触发错误。 - 触发条件:只有当
Interface的TypeTypeVar被设为逆变时才会出现此问题;将其改为协变或不变时,错误自动消失。修改SpecType的方差对该问题没有影响。 - 环境兼容性:Python 3.11.0和3.6.8版本中均存在此问题。
临时解决方案
可以将嵌套的Tuple[str, SpecType]封装为独立的泛型类,避免直接在继承语句中使用嵌套泛型类型,让Pylance能正确推断类型:
from typing import Generic, Tuple, TypeVar Type = TypeVar("Type", contravariant=True) class Interface(Generic[Type]): pass SpecType = TypeVar("SpecType") class StringSpecTuple(Generic[SpecType]): def __init__(self, s: str, spec: SpecType): self.value: Tuple[str, SpecType] = (s, spec) class Implementation(Interface[StringSpecTuple[SpecType]], Generic[SpecType]): pass a: Interface[StringSpecTuple[float]] = Implementation[float]()
内容的提问来源于stack exchange,提问作者Ethan Bull-vulpe
相关产品推荐
相关产品推荐

