这是我的代码,简化了很多(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
...
这似乎是一个错误(感谢@STerliakov 的确认)。报告于 mypy/#16707。