泛型类子类重写__new__时的mypy类型提示错误分析
泛型类__new__重写的mypy类型错误问题
问题代码
from typing import TypeVar, Generic T = TypeVar("T") class A(): pass class B(A, Generic[T]): def __new__(cls, x: T): return super().__new__(cls) class C(B[T]): def __new__(cls, x: T): return super().__new__(cls, x)
mypy错误信息
# Argument 1 to "__new__" of "B" has incompatible type "type[C[T]]"; expected "type[B[T]]" [arg-type] # Argument 2 to "__new__" of "B" has incompatible type "T"; expected "T" [arg-type]
用户疑问
- 除泛型外,这样重写__new__看似正常,已知
type[C]兼容type[B],为何type[C[T]]与type[B[T]]不兼容?我认为这与协变/逆变无关(已尝试调整)。 - 完全无法理解第二个错误的含义。
补充说明:未找到类似问题,查阅mypy泛型文档也无收获。这可能与mypy文档中“不兼容重写”相关,但错误信息不符,且该重写对__new__正常工作是必要的。
问题解析与解决方案
错误1:泛型元类型兼容性问题
mypy对泛型类的元类型(type[GenericClass[T]])的兼容性处理和非泛型类不同。非泛型场景下type[C]是type[B]的子类型,但泛型场景中,mypy默认不将type[C[T]]视为type[B[T]]的子类型——因为B的__new__方法中cls参数被推断为type[B[T]],子类C传入的cls是type[C[T]],二者未被mypy识别为兼容。
解决方法是通过绑定的TypeVar显式标注cls的类型范围:
from typing import TypeVar, Generic, Type T = TypeVar("T") # 定义绑定到B[T]子类的TypeVar BSubclass = TypeVar("BSubclass", bound="B[T]") class A(): pass class B(A, Generic[T]): def __new__(cls: Type[BSubclass], x: T) -> BSubclass: return super().__new__(cls) class C(B[T]): def __new__(cls: Type["C[T]"], x: T) -> "C[T]": return super().__new__(cls, x)
错误2:“T”类型不兼容的误导性提示
这个错误是第一个错误的衍生问题。当mypy无法正确识别cls的类型兼容性时,会破坏泛型上下文的推导,错误地判定传入的T和目标方法期望的T不匹配。只要修复第一个错误,这个提示会自动消失。
内容的提问来源于stack exchange,提问作者TrakJohnson
相关产品推荐
相关产品推荐

