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

动态创建Enum时如何注解test_func2以通过mypy检查

解决动态枚举的mypy类型检查问题

问题场景

以下代码运行正常,但执行mypy x.py时会触发类型检查错误:

from __future__ import annotations
from enum import Enum, auto
from typing import Type

class AEnum(Enum):
    VALUE1 = auto()
    VALUE2 = auto()


SPS_STATES = {
    "pre": "PreReleased",
    "rel": "Released",
    "ret": "Retired",
    "tgt": "Target"
}


SpsState = Enum('SpsState', list(SPS_STATES.values()))


def test_func() -> AEnum:
    return AEnum.VALUE1

def test_func2() -> Type[Enum]:
    return SpsState.Released

print(f'{test_func()}, {type(test_func())}, {[state.name for state in AEnum]}')
print(f'{test_func2()}, {type(test_func2())}, {[state.name for state in SpsState]}')

运行输出(符合预期)

AEnum.VALUE1, <enum 'AEnum'>, ['VALUE1', 'VALUE2']
SpsState.Released, <enum 'SpsState'>, ['PreReleased', 'Released', 'Retired', 'Target']

mypy错误信息

x.py:18: error: Second argument of Enum() must be string, tuple, list or dict literal for mypy to determine Enum members  [misc]
x.py:25: error: "type[SpsState]" has no attribute "Released"  [attr-defined]
Found 2 errors in 1 file (checked 1 source file)

需求:修正test_func2的类型注解,让mypy检查通过,且代码能自适应SPS_STATES字典的变更(不硬编码枚举值)。

错误原因

  1. 动态枚举无法被静态分析:SpsState通过list(SPS_STATES.values())动态生成,mypy无法静态推断枚举成员,因此提示参数类型错误,且识别不到SpsState.Released这个成员。
  2. 返回类型注解错误:test_func2返回的是枚举实例(SpsState.Released),但原注解Type[Enum]表示返回枚举类的类型,两者不匹配。

解决方案

修改后的完整代码

from __future__ import annotations
from enum import Enum, auto
from typing import cast

class AEnum(Enum):
    VALUE1 = auto()
    VALUE2 = auto()


SPS_STATES = {
    "pre": "PreReleased",
    "rel": "Released",
    "ret": "Retired",
    "tgt": "Target"
}


# 忽略mypy对动态枚举参数的检查,适配外部字典的动态变更
SpsState = Enum('SpsState', list(SPS_STATES.values()))  # type: ignore[misc]


def test_func() -> AEnum:
    return AEnum.VALUE1

def test_func2() -> SpsState:
    # 用getattr动态获取枚举成员,cast断言类型让mypy认可
    return cast(SpsState, getattr(SpsState, "Released"))

print(f'{test_func()}, {type(test_func())}, {[state.name for state in AEnum]}')
print(f'{test_func2()}, {type(test_func2())}, {[state.name for state in SpsState]}')

关键修改点

  1. 修正返回类型:将test_func2的返回注解改为SpsState,匹配实际返回的枚举实例类型。
  2. 动态获取枚举成员:用getattr(SpsState, "Released")替代直接访问SpsState.Released,避免mypy因无法识别动态成员而报错。
  3. 类型断言:用cast(SpsState, ...)告诉mypy获取到的对象是SpsState类型的实例。
  4. 忽略动态枚举参数检查:给SpsState的定义添加# type: ignore[misc],因为我们需要自适应动态字典的场景,无法使用字面量参数。

验证

执行mypy x.py后,不再出现类型检查错误,同时代码依然能根据SPS_STATES的变更自动更新枚举成员。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 17:42:47