如何解决mypy:“__setitem__”的签名与超类型“list”不兼容
我正在尝试使用 List 的一个专门子类来创建一个由常规列表支持的 TokenList,但还包含一个带有键/值的元数据字典。一切正常,直到我想为此添加类型,现在我收到此错误:
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,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]))"
您的原始代码的问题在于,列表可以被不仅仅是 int
和 slice
索引:它们支持任何可以使用 __index__
强制转换为整数的对象作为嗯。
这意味着您需要进行两项更改:导入 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)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。