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

mypy报错__iadd__与__add__签名不兼容,求排查方案

解决__iadd__与__add__签名不兼容的mypy报错问题

编写带维度类型检查的向量与矩阵代码时,在为__add__和__iadd__方法添加类型检查时遇到mypy报错:Signatures of "__iadd__" and "__add__" are incompatible,但两个方法的重载签名看似完全一致。

问题代码示例

from __future__ import annotations

from typing import (
    Generic,
    Literal as L,
    TypeVar, 
    overload,
    assert_type
)


_D1 = TypeVar("_D1")
_D2 = TypeVar("_D2")
_D3 = TypeVar("_D3")

# TypeVarTuple is an experimental feature; this is a work-around
class Shape:
    """Class that works as a tag to indicate that we are specifying a shape."""
class Shape1D(Shape, Generic[_D1]): pass
class Shape2D(Shape, Generic[_D1,_D2]): pass


_Shape = TypeVar("_Shape", bound=Shape)
Scalar = int | float


class Array(Generic[_Shape]):
    @overload # Adding with the same shape
    def __add__(self: Array[_Shape], other: Array[_Shape]) -> Array[_Shape]:
        return Any # type: ignore
    @overload # Adding with a scalar
    def __add__(self: Array[_Shape], other: Scalar) -> Array[_Shape]:
        return Any # type: ignore
    def __add__(self, other) -> Array:
        return self # Dummy implementation
        
    @overload # Adding with the same shape
    def __iadd__(self: Array[_Shape], other: Array[_Shape]) -> Array[_Shape]:
        return Any # type: ignore
    @overload # Adding with a scalar
    def __iadd__(self: Array[_Shape], other: Scalar) -> Array[_Shape]:
        return Any # type: ignore
    def __iadd__(self, other) -> Array:
        return self # Dummy implementation
    
    # Adding with a scalar
    def __radd__(self: Array[_Shape], other: Scalar) -> Array[_Shape]:
        return Any # type: ignore



A = Array[Shape2D[L[3],L[4]]]()

reveal_type(A + 1.0) ; assert_type(A + 1.0, Array[Shape2D[L[3],L[4]]])
reveal_type(1.0 + A) ; assert_type(1.0 + A, Array[Shape2D[L[3],L[4]]])
reveal_type(A + A)   ; assert_type(A + A,   Array[Shape2D[L[3],L[4]]])

A += 1.0
A += A

报错原因

mypy对就地操作符(如__iadd__)的类型规则有特殊要求:根据PEP 484规范,就地操作符的返回值应该严格匹配调用对象的自身类型。你的代码中,__iadd__的实现方法返回类型注解为Array(无泛型参数的原始类),而重载签名返回的是Array[_Shape],二者的泛型参数不一致,导致mypy判定签名不兼容。

解决方案

修改__iadd__实现方法的返回类型注解,从Array改为Array[_Shape],确保重载签名和实现的返回类型完全匹配。

修正后的代码

from __future__ import annotations

from typing import (
    Generic,
    Literal as L,
    TypeVar, 
    overload,
    assert_type
)


_D1 = TypeVar("_D1")
_D2 = TypeVar("_D2")
_D3 = TypeVar("_D3")

# TypeVarTuple is an experimental feature; this is a work-around
class Shape:
    """Class that works as a tag to indicate that we are specifying a shape."""
class Shape1D(Shape, Generic[_D1]): pass
class Shape2D(Shape, Generic[_D1,_D2]): pass


_Shape = TypeVar("_Shape", bound=Shape)
Scalar = int | float


class Array(Generic[_Shape]):
    @overload # Adding with the same shape
    def __add__(self: Array[_Shape], other: Array[_Shape]) -> Array[_Shape]:
        return Any # type: ignore
    @overload # Adding with a scalar
    def __add__(self: Array[_Shape], other: Scalar) -> Array[_Shape]:
        return Any # type: ignore
    def __add__(self, other) -> Array[_Shape]:
        return self # Dummy implementation
        
    @overload # Adding with the same shape
    def __iadd__(self: Array[_Shape], other: Array[_Shape]) -> Array[_Shape]:
        return Any # type: ignore
    @overload # Adding with a scalar
    def __iadd__(self: Array[_Shape], other: Scalar) -> Array[_Shape]:
        return Any # type: ignore
    def __iadd__(self, other) -> Array[_Shape]:
        return self # Dummy implementation
    
    # Adding with a scalar
    def __radd__(self: Array[_Shape], other: Scalar) -> Array[_Shape]:
        return Any # type: ignore



A = Array[Shape2D[L[3],L[4]]]()

reveal_type(A + 1.0) ; assert_type(A + 1.0, Array[Shape2D[L[3],L[4]]])
reveal_type(1.0 + A) ; assert_type(1.0 + A, Array[Shape2D[L[3],L[4]]])
reveal_type(A + A)   ; assert_type(A + A,   Array[Shape2D[L[3],L[4]]])

A += 1.0
A += A

验证效果

修正后,mypy将不再报签名不兼容的错误,所有类型断言和reveal_type的结果也会符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 18:01:20