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

Pyright字面量穷尽检查为何仅支持参数,不支持类属性?

Pyright穷尽检查的差异原因

以下代码可正常通过Pyright的穷尽检查:

from typing import Literal

def test(it: Literal['a', 'b']) -> str:
    if it == 'a':
        return 'a'
    elif it == 'b':
        return 'b'
    # No error, exhaustive

但下方代码无法通过检查:

from dataclasses import dataclass
from typing import Literal

@dataclass
class Foo:
    foo: Literal['a', 'b']

def test(it: Foo) -> str:
    foo = it.foo
    if foo == 'a':
        return 'a'
    elif foo == 'b': # Correctly infers that foo is Literal['b'] without the check
        return 'b'

    # Error, must return str

差异核心原因

这是Pyright对变量不可变性的推导逻辑差异导致的:

  • 第一个例子里,it是直接传入的函数参数,类型为Literal['a','b']。Pyright会认定这类参数是不可变的——函数执行过程中它的类型和值不会被修改,因此在覆盖了'a'和'b'两个分支后,Pyright能确定已经穷尽了所有可能的取值,不会触发“未返回值”的错误。
  • 第二个例子里,foo是从数据类实例中提取的局部变量。Pyright默认不会假设数据类的属性是完全不可变的(哪怕你没定义setter,静态分析阶段也无法100%排除其他代码修改该属性的可能)。因此Pyright会保留“foo的类型可能被意外改变”的可能性,不会认为两个分支已经覆盖了所有情况,最终提示函数可能没有返回值的错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 06:02:39