【发布时间】:2020-04-24 16:07:49
【问题描述】:
当协议被用作类型注释函数的简单参数时,Mypy 可以正确识别类对协议的遵守情况。但是,当我有一个需要使用该协议的可调用参数的函数时,Mypy 会错过用户类的协议成员资格。
我是在滥用 Mypy 的协议模式,还是 Mypy 目前根本不支持这种模式?
(我已经看到有关 Mypy 遇到 Callables 问题的帖子that get assigned to a class.. 所以这可能是已知行为)
from typing_extensions import Protocol
from typing import Callable
class P(Protocol) :
def foo(self) -> None : ...
def requires_P(protocol_member : P) -> None :
protocol_member.foo()
def requires_P_callable(protocol_member : P, function: Callable[[P],None]) -> None :
function(protocol_member)
class C :
def foo(self) :
print("bar")
if __name__ == '__main__' :
c = C()
def call_foo(c: C) -> None:
c.foo()
requires_P(c)
# mypy is fine with this
requires_P_callable(c, call_foo)
# mypy complains :
# Argument 2 to "requires_P_callable" has incompatible type "Callable[[C], None]"; expected "Callable[[P], None]"
【问题讨论】:
-
它看起来像
mypy中的一个错误 -
我不确定:python.org/dev/peps/pep-0483/#covariance-and-contravariance 请阅读有关 Callables 的协变和逆变。
-
谢谢安德鲁。我不知道 Callables 中参数的逆变性,所以这对我非常有帮助。尽管在我的示例中 C 严格来说不是 P 的子类型,但我想 co/contra -variance 与 Mypy 如何检查协议模式有关?
标签: python mypy protocol-oriented