【发布时间】:2021-10-19 15:42:03
【问题描述】:
我无法弄清楚这是否可能。
鉴于以下代码,我希望mypy 报告两种情况的错误:
from dataclasses import dataclass
from typing import Generic, Protocol, Type, TypeVar
T = TypeVar("T")
class MyProto(Protocol):
attr: str
class Impl:
attr: int # wrong type on purpose for this example
# This util class is an attempt to illustrate what I'm trying to achieve, an answer may very well
# indicate changes to it, if required, to make it work as desired.
@dataclass
class Util(Generic[T]):
proto: T
impl: Type[T]
# Case 1
# The following is type checked, and correctly reports the error when the implementation does not
# satisfy the protocol.
C: Type[MyProto] = Impl
# Case 2
# Where as this is accepted regardless, but I'd like it to report error in case Impl does not
# satisfy MyProto.
util = Util(MyProto, Impl)
示例输出:
$ python -m mypy t.py
t.py:22:20: error: Incompatible types in assignment (expression has type "Type[Impl]", variable has type "Type[MyProto]") [assignment]
C: Type[MyProto] = Impl
^
Found 1 error in 1 file (checked 1 source file)
用例是,能够动态注册实现及其支持的协议,同时仍然进行静态类型检查。希望这是有道理的。
更新
好的,所以我发现我上面的内容应该可以正常工作,只要 Protocol 有一个可以实际工作的类型表示。现在,T 被推断为object 而不是MyProto,因为这是传递给Util() 的两种类型的最小公分母。但是,如果我明确声明 T 应该是 MyProto,我会更接近:
util = Util[MyProto](MyProto, Impl)
几乎给了我想要的东西:
[...]
t.py:42:22: error: Argument 1 to "Util" has incompatible type "Type[MyProto]"; expected "MyProto" [arg-type]
util = Util[MyProto](MyProto, Impl)
^
t.py:42:31: error: Argument 2 to "Util" has incompatible type "Type[Impl]"; expected "Type[MyProto]" [arg-type]
util = Util[MyProto](MyProto, Impl)
^
参数1的错误是错误的,期望的类型是正确的,参数的报告类型是错误的,应该只是MyProto或者协议类应该用类型系统来表示。
关于参数 2 的错误是正确的,如果我修复 Impl 使其与协议匹配,它就会消失。
因此,在协议方面,缺乏适当的类型表示以及确定两种类型之间 LCD 的逻辑似乎被打破了。
【问题讨论】:
-
并关闭。改为使用 ABC。
标签: python type-hinting mypy typechecking python-typing