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

Mypy对自定义list子类的__setitem__重载签名报错如何解决?

报错根本原因

mypy在处理重载方法的调用时,不会对Union类型的入参做自动的重载分支匹配,只会优先尝试匹配第一个重载定义。
你子类定义的__setitem__虽然有两个正确的重载分支,但是在调用super().__setitem__时,传入的index是Union[SupportsIndex, slice]类型,value是Union[MyData, Iterable[MyData]]类型,mypy会直接用这两个Union类型去匹配父类list的__setitem__的第一个重载:

def __setitem__(self, index: SupportsIndex, value: MyData) -> None

自然就会报「索引类型不匹配」「值类型不匹配」的错误。
而__delitem__没有重载,它的签名本身就接受Union[SupportsIndex, slice]类型的入参,所以传Union参数不会触发错误。

正确解决方法

最简单的无忽略实现是通过显式分支缩小参数类型,让mypy可以匹配到对应的重载分支:

from typing import List, Iterable, Union, overload, cast
from typing_extensions import SupportsIndex


class MyData:
    pass


class MyDataSeq(List[MyData]):
    @overload
    def __setitem__(self, index: SupportsIndex, value: MyData) -> None: ...

    @overload
    def __setitem__(self, index: slice, value: Iterable[MyData]) -> None: ...

    def __setitem__(self, index: Union[SupportsIndex, slice], value: Union[MyData, Iterable[MyData]]) -> None:
        # Administrative stuff deleted
        if isinstance(index, slice):
            super().__setitem__(index, cast(Iterable[MyData], value))
        else:
            super().__setitem__(index, cast(MyData, value))

    def __delitem__(self, index: Union[SupportsIndex, slice]) -> None:
        # Administrative stuff deleted
        super().__delitem__(index)

这里的cast是零运行时代价的类型标注,用来告诉mypy当前分支下value的确定类型,符合你重载定义的参数对应规则,不会影响实际运行逻辑。
如果你接受局部忽略mypy错误,也可以直接在调用行加# type: ignore[arg-type],但显式分支的方案更符合类型安全要求,可维护性更高。

内容的提问来源于stack exchange,提问作者Ruud de Jong

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 03:39:03