从 Union 创建受约束的 TypeVar

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

在以下代码上运行 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 generics python-typing mypy
1个回答
0
投票

不幸的是,没有。

当前(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”的方法。

© www.soinside.com 2019 - 2024. All rights reserved.