如何修复mypy数值类型返回值不兼容报错并保留原help输出
问题描述
参考如下示例代码:
from typing import TypeVar Even = TypeVar("Even",bound=int) Odd = TypeVar("Odd",bound=int) def make_even(n:int) -> Even: return n*2 def make_odd(n:int) -> Odd: return n*2+1 def make_both(n:int) -> tuple[Even,Odd]: return make_even(n), make_odd(n) help(make_both)
上述代码运行后help(make_both)的输出完全符合预期,输出内容如下:
Help on function make_both in module __main__: make_both(n: int) -> tuple[~Even, ~Odd]
但mypy检查时会抛出如下类型错误:
test5.py:8: error: Incompatible return value type (got "int", expected "Even") test5.py:11: error: Incompatible return value type (got "int", expected "Odd") Found 2 errors in 1 file (checked 1 source file)
需求为:除了使用#type: ignore注释忽略报错之外,调整代码既能通过mypy类型检查,又能保留原有友好的help输出效果。
解决方案
报错的核心原因是:定义TypeVar时指定bound=int仅约束该类型变量必须是int的子类型,但算术运算得到的原生int值不会被mypy自动推导为Even/Odd子类型,直接返回就会触发类型不匹配错误。
使用typing.cast做显式类型声明即可解决问题,该方法仅在类型检查阶段生效,无任何运行时开销,也不会改变原有类型标注的help输出效果,调整后代码如下:
from typing import TypeVar, cast Even = TypeVar("Even", bound=int) Odd = TypeVar("Odd", bound=int) def make_even(n: int) -> Even: return cast(Even, n * 2) def make_odd(n: int) -> Odd: return cast(Odd, n * 2 + 1) def make_both(n: int) -> tuple[Even, Odd]: return make_even(n), make_odd(n) help(make_both)
调整后效果验证:
- mypy静态检查无任何报错
- 运行代码后
help(make_both)输出和原效果完全一致,仍显示make_both(n: int) -> tuple[~Even, ~Odd] - 无额外运行时成本,
cast在运行时会直接返回传入的值,不做实际转换操作
注意不要使用NewType定义Even、Odd类型,NewType会生成独立的类型对象,会导致help输出丢失原有的泛型类型变量显示效果,不符合需求。
内容的提问来源于stack exchange,提问作者Copperfield
相关产品推荐
相关产品推荐

