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

Mypy报[override]错误‘方法签名与超类型不兼容’是否为误判?

Mypy报[override]错误‘方法签名与超类型不兼容’是否为误判?

我最近碰到一个挺费解的问题:明明子类的方法签名从**里氏替换原则(LSP)**来看完全合规,但mypy却抛出了Signature of "method" incompatible with supertype "Super"的[override]错误。先跟大家说下我的环境:

  • Python 3.13.1
  • mypy 1.14.0

我写了这样一个test.pyi类型提示文件:

from typing import overload

class Super:
    def method(self, arg:Other|Super)->Super: pass

class Sub(Super):
    @overload
    def method(self, arg:Other|Sub)->Sub: pass
    @overload
    def method(self, arg:Super)->Super: pass

class Other: pass

运行mypy test.pyi后,得到了如下错误输出:

test.pyi:7: error: Signature of "method" incompatible with supertype "Super"  [override]
test.pyi:7: note:      Superclass:
test.pyi:7: note:          def method(self, arg: Other | Super) -> Super
test.pyi:7: note:      Subclass:
test.pyi:7: note:          @overload
test.pyi:7: note:          def method(self, arg: Other | Sub) -> Sub
test.pyi:7: note:          def method(self, arg: Super) -> Super
Found 1 error in 1 file (checked 1 source file)

我仔细对比了父类和子类方法的输入输出类型,完全没找到违反LSP的地方:
子类的重载方法其实完全覆盖了父类的输入范围(Other|Super = Other|Sub + Super),输出类型也满足LSP要求——要么和父类一致,要么是更窄的子类型。

我还做了一张输入输出对照表来验证:

I\OSuper.methodSub.method对比父类,子类返回类型是否符合LSP*
OtherSuperSub更窄是
SubSuperSub更窄是
SuperSuperSuper一致是
Other|SubSuperSub更窄是
Other|SuperSuperSuper**一致是

*LSP要求子类方法的返回类型必须是父类返回类型的子类型(更窄)或完全一致。
**当输入为Other|Super时,子类方法会根据输入分别返回Sub或Super,最终返回类型是Sub|Super,而Sub是Super的子类,所以整体等价于Super。

从表格能看出来,所有场景都符合LSP规范,那为什么mypy会报错呢?是我的代码哪里写错了,还是mypy的误判?如果是mypy的问题,我该去哪里反馈?


临时规避方法(非完美解决方案)

我找到了一个能暂时隐藏错误的办法,虽然不是根本解决方法,但可以先应付当前场景:

from typing import overload

class Super:
    def method(self, arg:Other|Super)->Super: pass

class Sub(Super):
    @overload
    def method(self, arg:Other|Sub)->Sub: pass
    @overload
    def method(self, arg:Super)->Super: pass
    # 开始隐藏错误
    @overload
    def method( # type: ignore[overload-cannot-match]
               self, arg:Other|Super)->Super: pass
    # 结束隐藏错误

class Other: pass

就是在子类的重载最后,加一个和父类完全一致的签名。不过等未来mypy修复这个问题后,这个新增的重载会因为无法匹配触发[overload-cannot-match]错误,所以我提前加了# type: ignore[overload-cannot-match]来规避。(这不是单纯用ignore压制错误,而是提前预防未来可能出现的问题)

备注:内容来源于stack exchange,提问作者平田智剛

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 12:28:08