两个 @runtime_checkable 协议联合的类型别名会触发 mypy 的“无法在实例检查中使用参数化泛型”

问题描述 投票:0回答:1

这是我的代码,简化了很多(playground使用

_typeshed.SupportsTrunc
):

from typing import Protocol, runtime_checkable, SupportsIndex, SupportsInt


@runtime_checkable
class SupportsTrunc(Protocol):
    
    def __trunc__(self) -> int:
        ...


_ConvertibleToInt = SupportsInt | SupportsIndex | SupportsTrunc
def f(o: object) -> None:
    if isinstance(o, _ConvertibleToInt):
        # error: Parameterized generics cannot be used with class or instance checks
        # error: Argument 2 to "isinstance" has incompatible type "<typing special form>"; expected "_ClassInfo"
        ...

所有三个

Protocol
都是
@runtime_checkable
。据我所知,这些显然没有像 mypy 声称的那样参数化。我究竟做错了什么?或者这是一个 mypy bug?


感谢@wjandrea,我找到了一个更简单的例子:

from typing import SupportsIndex, SupportsInt

_ConvertibleToInt = SupportsInt | SupportsIndex

def f(o: object) -> None:
    if isinstance(o, _ConvertibleToInt):  # error
        ...

如果没有别名,则不会发生相同的错误(playground):

def f(o: object) -> None:
    if isinstance(o, SupportsInt | SupportsIndex):  # fine
        ...

...或者如果别名是一个

Protocol
而不是联合 (playground):

_ConvertibleToInt = SupportsInt

def f(o: object) -> None:
    if isinstance(o, _ConvertibleToInt):  # fine
        ...

相同

Protocol
的并集重复两次仍然会触发此错误(playground):

_ConvertibleToInt = SupportsInt | SupportsInt

def f(o: object) -> None:
    if isinstance(o, _ConvertibleToInt):  # error
        ...
python mypy type-hinting
1个回答
0
投票

这似乎是一个错误(感谢@STerliakov 的确认)。报告于 mypy/#16707

© www.soinside.com 2019 - 2024. All rights reserved.