假设我正在尝试为一个为用户定义类型注册反序列化器的库函数编写类型提示:用户应该提供一个类型
T
以及一个函数 decode: str -> T
。
我认为用 python 的 PEP-484 类型提示编写此代码的最自然方法如下:
from typing import Callable, Type, TypeVar
T = TypeVar("T")
def register_decoder(type_: Type[T], decode: Callable[[str], T]):
...
对我来说不幸的是,
Type[T]
在T
中是协变的,这意味着这对解码函数来说不够严格:至少在pyright中,调用register_decoder(int, decode=str)
通过了类型检查,类型变量T
已解析作为工会int | str
:
有没有一种方法可以类型提示此方法,强制执行
decode
返回 type_
实例的约束,以便此示例会引发错误,因为 str
不返回 int
?可以完成这项工作的一件事是 Type[T]
的非协变等价物,它只接受 exact 类对象 T
而不是任何子类型,但我不确定 Python 中是否存在这样的东西。
使用
mypy --strict
给出了预期的错误。必须是特定于您正在使用的 linter 的东西。
from typing import Callable, Type, TypeVar
T = TypeVar("T")
def register_decoder(type_: Type[T], decode: Callable[[str], T]) -> None:
return
register_decoder(int, str)
>mypy --strict test.py
test.py:6: error: Argument 2 to "register_decoder" has incompatible type "Type[str]"; expected "Callable[[str], int]"
Found 1 error in 1 file (checked 1 source file)
>python --version
Python 3.9.5
>mypy --version
mypy 0.910