我有一个 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
object 作为它的第一个参数。几乎就像mypy
不知何故得出的结论只有int
支持类似对象——它与第二个错误相匹配,它只需要 MyData
作为第二个参数,不是 Iterable[MyData]
.我在 Python 3.7 和 3.9 上都试过这个,错误是一样的。
我当然可以告诉
mypy
忽略这些错误,但我真的很想知道是什么原因造成的,以及如何解决它。有任何想法吗?
最佳答案
按照this类似的问题。 Mypy 不使用重载信息对函数体进行类型检查。
要解决您的问题,您可以 give a hint到 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)
关于python - Mypy 提示 __setitem__ 签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68473151/