python - Mypy 提示 __setitem__ 签名

标签 python mypy

我有一个 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/

相关文章:

Python >=3.5 : Checking type annotation at runtime

python - Mypy 提示默认参数值与省略号不兼容

python - Mypy 捕获 AttributeError

python-3.x - 在 MyPy 中使用 TypeVar 输入带参数的装饰器会产生预期的无人居住类型

Python 3-x 使用类似 SQL 的条件从 CSV 表中选择列和行

python - 在数组中存储按钮和其他 wx 小部件

python - 更改 file.index 的默认 ValueError

python - 如何从 Python 触发 Google Analytics 事件?

python - 如何强制 Theano 在 GPU 上并行化操作(测试用例 : numpy. bincount)

python - 我可以只对更改的代码执行静态分析吗?