python - Mypy 抱怨 __setitem__ 签名
问题描述
我有一个子类,list
它在列表的组件上添加了一些管理内容。一切正常,但mypy
抱怨super
调用的签名__setitem__
。这是问题减少到最低限度:
from typing import List, Iterable, Union, overload
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
super().__setitem__(index, value)
def __delitem__(self, index: Union[SupportsIndex, slice]) -> None:
# Administrative stuff deleted
super().__delitem__(index)
当我运行mypy
这个时,我得到:
src\seq.py:18: error: Invalid index type "Union[SupportsIndex, slice]" for "MyDataSeq"; expected type "SupportsIndex"
src\seq.py:18: error: Incompatible types in assignment (expression has type "Union[MyData, Iterable[MyData]]", target has type "MyData")
Found 2 errors in 1 file (checked 1 source file)
我在这里不知所措,因为显然__setitem__
,就像 一样__delitem__
,接受一个int
-like ( SupportsIndex
) 和一个slice
对象作为它的第一个参数。几乎好像mypy
以某种方式得出了仅int
支持 -like 对象的结论 - 这与第二个错误相匹配,它只期望 aMyData
作为第二个参数,而不是Iterable[MyData]
.
我在 Python 3.7 和 3.9 上都试过这个,错误是一样的。我当然可以告诉mypy
忽略这些错误,但我真的很想知道是什么原因造成的,以及如何解决它。有任何想法吗?
解决方案
按照这个类似的问题。Mypy 不使用重载信息对函数体进行类型检查。
为了解决您的问题,您可以通过isinstance
. 像这样:
from typing import List, Iterable, Union, overload
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) and isinstance(value, Iterable):
super().__setitem__(index, value)
elif isinstance(index, int) and isinstance(value, MyData):
super().__setitem__(index, value)
else:
raise TypeError(f"{index}/{value} Invalid index/value type.")
def __delitem__(self, index: Union[SupportsIndex, slice]) -> None:
# Administrative stuff deleted
super().__delitem__(index)
推荐阅读
- java - 我如何在java中进行像素完美升级?
- symfony - 清除产品缓存。环境。在 Orocommerce
- docker - 如何使用 docker 在 jvm 中设置时区
- bash - 使用 sed 清理文件以获取环境配置
- python-3.x - 如何让不和谐机器人使用 discord.py 触发它自己的消息上的命令?
- node.js - 有没有办法我可以跟踪模型中更改的时间和实体
- javascript - 将字符串转换为 DOM 后,对象作为 React 子项无效
- c - 无法完成写入 EEPROM,因为它会重置电路板
- javascript - 将 JQuery 函数从 keyup 更改为提交
- aws-lambda - 我可以在 AWS Cognito 中为 sign_in 和 sign_up 过程设置不同的回调 URL 吗?