使用MyPy时无约束TypeVar类型推断错误原因咨询
问题
我用以下代码配合MyPy做类型检查:
from typing import TypeVar T = TypeVar("T") def mul3(x: T) -> T: return 3 * x for x in [4, 6, 3.4]: print(f"{x=}, {mul3(x)=}")
得到报错:
example.py:7: error: Incompatible return value type (got "int", expected "T") example.py:7: error: Unsupported operand types for * ("int" and "T")
把TypeVar改为T = TypeVar("T", int, float)后代码能正常通过检查。我理解返回值类型需要和参数类型T一致,但疑惑为什么参数类型无法被推断为int,特此咨询原因。
解答
无约束TypeVar的本质
无约束的TypeVar("T")代表任意类型,MyPy会严格校验这个泛型函数是否对所有可能的T类型都成立,而不是只针对你当前调用时传入的int/float。报错的核心原因
- 第一个错误
Unsupported operand types for * ("int" and "T"):MyPy无法确认任意类型T都支持和int做乘法运算——比如字符串、列表虽然能和int相乘,但这属于特定类型的行为,不是所有类型都具备,所以MyPy会判定这个操作不合法。 - 第二个错误
Incompatible return value type (got "int", expected "T"):即使忽略乘法的合法性,3*x的返回类型在MyPy看来是int,但泛型参数T可能是任意类型(比如str、bool),无法保证返回的int和输入的T类型一致,因此类型不匹配。
- 第一个错误
为什么不能推断为int
泛型函数的类型约束是针对函数本身的,不是针对单次调用。你当前调用时传入了int和float,但MyPy不会因为这一次调用就把T的范围缩小到int——它要确保这个函数在任何合法的T输入下都能符合类型约定,而无约束的T显然做不到这一点。约束TypeVar后的作用
当你把T约束为int, float时,MyPy明确知道T只能是这两种数值类型:- 这两种类型都支持和int做乘法运算;
- 乘法后的返回类型和输入类型一致(intint=int,intfloat=float);
因此类型检查可以顺利通过。
内容的提问来源于stack exchange,提问作者Bychan
相关产品推荐
相关产品推荐

