继承NamedTuple时mypy报重载签名冲突错误的原因及是否需提交Issue咨询
继承NamedTuple时mypy报重载签名冲突错误的原因及是否需提交Issue咨询
看起来你遇到了一个挺让人困惑的mypy类型检查问题,我来帮你拆解分析下:
首先,先复现你的问题场景,你的代码如下:
from typing import overload, NamedTuple class A(NamedTuple): pass class B(NamedTuple): pass @overload def frobnicate(arg: A) -> A: ... @overload def frobnicate(arg: B) -> B: ... def frobnicate(arg: A | B) -> A | B: if isinstance(arg, A): return A() elif isinstance(arg, B): return B() else: raise TypeError()
运行mypy后会触发错误:
error: Overloaded function signatures 1 and 2 overlap with incompatible return types [overload-overlap]
你提到这个问题只在继承NamedTuple时出现,换成tuple、dict或object作为父类就不会有这个报错,这确实是mypy对NamedTuple的特殊处理导致的异常行为。
为什么会出现这个问题?
NamedTuple在mypy的类型系统里有特殊的逻辑处理:虽然A和B是两个完全独立的自定义类,但mypy可能错误地认为它们之间存在某种隐式的类型兼容(比如都属于NamedTuple生成的tuple子类,导致类型判断出现混淆),从而误判两个重载签名存在重叠冲突。而对于普通的tuple、dict子类,mypy的类型检查逻辑是正常的,能正确识别它们是独立类型。
是否需要提交Issue?
当然需要!这个明显是mypy的一个bug——你的重载签名逻辑是完全合理的,两个独立的NamedTuple子类作为参数的重载不应该被判定为重叠冲突。尤其是你提到实际代码里的重载是f(A)->B和f(B)->A,这种场景下根本没法用TypeVar来替代重载,更凸显了这个问题的影响。
提交Issue的时候,记得带上这些信息:
- 你的最小复现代码
- 说明该错误仅在继承
NamedTuple时触发,其他父类无此问题 - 补充你实际代码中的重载场景(
A→B、B→A),帮助维护者理解问题的实际影响
备注:内容来源于stack exchange,提问作者mqnc
相关产品推荐
相关产品推荐

