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

移除返回类型Any后Pyright报错:所有代码路径需返回int类型

解决Pyright返回类型检查报错问题

报错原因

Pyright无法确认Exp类的所有子类都被match语句覆盖,默认认为存在未处理的代码分支,会返回None,与你声明的int返回类型冲突——哪怕你实际没有定义其他Exp子类,类型检查器也无法静态推断这一点。

解决方案

方案1:标记Exp为密封类(推荐)

利用Pyright支持的@sealed装饰器(对应你提到的PEP草案),明确告知类型检查器Exp的所有子类都已在当前代码中定义,不存在其他子类。

需要先导入sealed:

  • Python 3.12+:从typing导入
  • 旧版本:从typing_extensions导入

修改后的代码:

from dataclasses import dataclass
# Python 3.12+用下面这行,否则替换为 from typing_extensions import sealed
from typing import sealed

@sealed
class Exp:
    pass

@dataclass
class Const(Exp):
    value: int

@dataclass
class Negate(Exp):
    value: Exp

@dataclass 
class Add(Exp):
    value1: Exp
    value2: Exp

@dataclass
class Multiply(Exp):
    value1: Exp
    value2: Exp


def eval_exp_old(e: Exp) -> int:
    match e:
        case Const(i):
            return i
        case Negate(e2):
            return -eval_exp_old(e2)
        case Add(e1, e2):
            return eval_exp_old(e1) + eval_exp_old(e2)
        case Multiply(e1, e2):
            return eval_exp_old(e1) * eval_exp_old(e2)

方案2:添加兜底分支抛出异常

如果不想使用密封类,可以在match语句末尾添加一个兜底分支,直接抛出异常,确保所有代码路径要么返回int,要么终止执行(不会返回None)。

修改后的函数:

def eval_exp_old(e: Exp) -> int:
    match e:
        case Const(i):
            return i
        case Negate(e2):
            return -eval_exp_old(e2)
        case Add(e1, e2):
            return eval_exp_old(e1) + eval_exp_old(e2)
        case Multiply(e1, e2):
            return eval_exp_old(e1) * eval_exp_old(e2)
        case _:
            raise ValueError(f"Unsupported Exp type: {type(e).__name__}")

补充说明

你原来的返回类型int | Any是冗余的,因为所有分支都明确返回int,直接声明-> int即可。

内容的提问来源于stack exchange,提问作者Adrian

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 16:43:21