在以下代码上运行 mypy 不会产生任何问题。
from typing import TypeVar
S = TypeVar("S", int, float, complex)
def func(x: list[S], m: S) -> list[S]:
return [val * m for val in x]
out1: list[int] = func([1, 2, 3], 4)
out2: list[complex] = func([1., 2., 3.], 4.)
但是下面的代码
from typing import TypeVar
Number = int | float | complex
S = TypeVar("S", bound=Number)
def func(x: list[S], m: S) -> list[S]:
return [val * m for val in x]
out1: list[int] = func([1, 2, 3], 4)
out2: list[complex] = func([1., 2., 3.], 4.)
报道
y.py:7: error: List comprehension has incompatible type List[Union[int, float, complex]]; expected List[S] [misc]
y.py:7: error: Unsupported operand types for * (likely involving Union) [operator]
为了避免 mypy 问题,我认为我需要从 Union 创建一个受约束的 TypeVar (我是从另一个包导入的,因此原则上不在我的控制范围内)。有办法实现吗?是否有另一种方法(没有 #type:ignore)来避免出现 mypy 问题?
不幸的是,没有。
当前(Python 3.14),有两种方法来创建约束
TypeVar
:
# 1. The TypeVar class
from typing import TypeVar
T = TypeVar('T', Constraint1, Constraint2)
def f(v: T) -> T: ...
# 2. PEP 695 syntax
def f[T: (Constraint1, Constraint2)](v: T) -> T: ...
两者都需要一个硬编码的约束列表。
我不知道有任何解决方法,甚至是“hacky”的方法。