You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 06:30:54