是否存在非协变`Type[T]`?

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

假设我正在尝试为一个为用户定义类型注册反序列化器的库函数编写类型提示:用户应该提供一个类型

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
:

pyright's inference of int|str

有没有一种方法可以类型提示此方法,强制执行

decode
返回
type_
实例的约束,以便此示例会引发错误,因为
str
不返回
int
?可以完成这项工作的一件事是
Type[T]
的非协变等价物,它只接受 exact 类对象
T
而不是任何子类型,但我不确定 Python 中是否存在这样的东西。

python python-typing higher-order-functions invariance
1个回答
1
投票

使用

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
© www.soinside.com 2019 - 2024. All rights reserved.