mypy:“__setitem__”的签名与超类型 "list" 不兼容

mypy: Signature of "__setitem__" incompatible with supertype "list"

我正在尝试使用 List 的一个专门子类来创建一个由常规列表支持的 TokenList,但还包含一个带有 key/values 的元数据字典。一切都很好,直到我想为此添加类型,现在我收到此错误:

error: Signature of "__setitem__" incompatible with supertype "list"

...错误是下面的第一个重载:

import typing as T

class Token(dict):
    ...

class TokenList(T.List[Token]):
    ...

    @T.overload
    def __setitem__(self, key: int, tokens: T.Union[dict, Token]) -> None: ...  # noqa, pragma: no cover

    @T.overload
    def __setitem__(self, key: slice, tokens: T.Union[T.Iterable[T.Union[dict, Token]], 'TokenList']) -> None: ...  # noqa, pragma: no cover

    def __setitem__(self, key, tokens):  # noqa: F811
        if isinstance(key, int):
            token = tokens
            token = self._dict_to_token_and_set_defaults(token)
            super(TokenList, self).__setitem__(key, token)
        else:
            tokens = [self._dict_to_token_and_set_defaults(token) for token in tokens]
            super(TokenList, self).__setitem__(key, tokens)

我试图找到 list 的类型定义以将其与我的进行比较,但未能找到。

除了忽略这个错误继续我的生活,还有什么办法解决这个问题吗?任何指点表示赞赏。

(如果重要的话,我正在使用 mypy 0.910 和 Python 3.9.1。)

你可以用reveal_type找出任何对象的静态类型。所以尝试:

reveal_type(list.__setitem__)

给你:

reveal_type.py:2: note: Revealed type is "Overload(def [_T] (builtins.list[_T`1], typing_extensions.SupportsIndex, _T`1), def [_T] (builtins.list[_T`1], builtins.slice, typing.Iterable[_T`1]))"

您的原始代码的问题是,列表可以索引的不仅仅是 ints 和 slices:它们支持任何可以用 [=22= 强制转换为整数的对象] 还有。

这意味着您需要进行两项更改:导入 typing_extensions 并将 int 替换为 typing_extensions.SupportsIndex

import typing_extensions as TE

...

def __setitem__(self, key: TE.SupportsIndex, tokens: T.Union[dict, Token]) -> None: ...  # noqa, pragma: no cover

此外,这意味着您的实现不太正确,因为非整数非切片索引将被视为切片索引。我会这样写:

def __setitem__(self, key, tokens):  # noqa: F811
    if isinstance(key, slice):
        tokens = [self._dict_to_token_and_set_defaults(token) for token in tokens]
    else:
        tokens = self._dict_to_token_and_set_defaults(tokens)
    super().__setitem__(key, tokens)