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

重写Literal类型参数方法时overrides触发RecursionError

问题描述

当重写带有Literal类型标注参数的方法时,第三方overrides模块会抛出RecursionError,栈追踪信息见下文。目前既不清楚该错误的触发原因,也不确定带Literal标注的方法是否支持正常重写。

补充说明:此处提到的overrides为第三方模块,项目仓库地址为github.com/mkorpela/overrides

可复现该错误的最小示例代码如下:

from typing import Literal

from overrides import overrides


class Base:
    def foo(self, mode: Literal["train"]) -> None:
        raise NotImplementedError()


class Child(Base):
    @overrides
    def foo(self, mode: Literal["train"]) -> None:
        pass

移除@overrides装饰器是可行的临时规避方案,不会改变代码实际运行行为,但优先希望保留该装饰器。原本计划将该参数类型替换为Enum,这也是设计层面更优的实现方案,但仍希望明确@overrides与Literal组合使用无法正常工作的根本原因。

错误栈追踪
Traceback (most recent call last):
  File "model-autotraining/temp.py", line 12, in <module>
    class ChildModel(BaseClass):
  File "model-autotraining/temp.py", line 14, in ChildModel
    def foo(self, mode: Literal["train"]) -> None:
  File "/opt/homebrew/Caskroom/miniforge/base/envs/worker/lib/python3.8/site-packages/overrides/overrides.py", line 88, in overrides
    return _overrides(method, check_signature, check_at_runtime)
  File "/opt/homebrew/Caskroom/miniforge/base/envs/worker/lib/python3.8/site-packages/overrides/overrides.py", line 114, in _overrides
    _validate_method(method, super_class, check_signature)
  File "/opt/homebrew/Caskroom/miniforge/base/envs/worker/lib/python3.8/site-packages/overrides/overrides.py", line 135, in _validate_method
    ensure_signature_is_compatible(super_method, method, is_static)
  File "/opt/homebrew/Caskroom/miniforge/base/envs/worker/lib/python3.8/site-packages/overrides/signature.py", line 94, in ensure_signature_is_compatible
    ensure_all_kwargs_defined_in_sub(
  File "/opt/homebrew/Caskroom/miniforge/base/envs/worker/lib/python3.8/site-packages/overrides/signature.py", line 153, in ensure_all_kwargs_defined_in_sub
    and not _issubtype(super_type_hints[name], sub_type_hints[name])
  File "/opt/homebrew/Caskroom/miniforge/base/envs/worker/lib/python3.8/site-packages/overrides/signature.py", line 42, in _issubtype
    return issubtype(left, right)
  File "/opt/homebrew/Caskroom/miniforge/base/envs/worker/lib/python3.8/site-packages/typing_utils/__init__.py", line 428, in issubtype
    return _is_normal_subtype(normalize(left), normalize(right), forward_refs)
  File "/opt/homebrew/Caskroom/miniforge/base/envs/worker/lib/python3.8/site-packages/typing_utils/__init__.py", line 251, in normalize
    args = _normalize_args(args)
  File "/opt/homebrew/Caskroom/miniforge/base/envs/worker/lib/python3.8/site-packages/typing_utils/__init__.py", line 232, in _normalize_args
    return tuple(_normalize_args(type_) for type_ in tps)
  File "/opt/homebrew/Caskroom/miniforge/base/envs/worker/lib/python3.8/site-packages/typing_utils/__init__.py", line 232, in <genexpr>
    return tuple(_normalize_args(type_) for type_ in tps)
  File "/opt/homebrew/Caskroom/miniforge/base/envs/worker/lib/python3.8/site-packages/typing_utils/__init__.py", line 232, in _normalize_args
    return tuple(_normalize_args(type_) for type_ in tps)
  File "/opt/homebrew/Caskroom/miniforge/base/envs/worker/lib/python3.8/site-packages/typing_utils/__init__.py", line 232, in <genexpr>

... repeated many times ...

  File "/opt/homebrew/Caskroom/miniforge/base/envs/worker/lib/python3.8/site-packages/typing_utils/__init__.py", line 232, in _normalize_args
    return tuple(_normalize_args(type_) for type_ in tps)
  File "/opt/homebrew/Caskroom/miniforge/base/envs/worker/lib/python3.8/site-packages/typing_utils/__init__.py", line 232, in <genexpr>
    return tuple(_normalize_args(type_) for type_ in tps)
  File "/opt/homebrew/Caskroom/miniforge/base/envs/worker/lib/python3.8/site-packages/typing_utils/__init__.py", line 231, in _normalize_args
    if isinstance(tps, collections.abc.Sequence):
  File "/opt/homebrew/Caskroom/miniforge/base/envs/worker/lib/python3.8/abc.py", line 98, in __instancecheck__
    return _abc_instancecheck(cls, instance)
  File "/opt/homebrew/Caskroom/miniforge/base/envs/worker/lib/python3.8/abc.py", line 102, in __subclasscheck__
    return _abc_subclasscheck(cls, subclass)
RecursionError: maximum recursion depth exceeded in comparison
问题根因

该错误是overrides依赖的typing_utils库在Python 3.8及以下版本中的类型解析bug导致的:

  • Python 3.8版本的typing.Literal实现未被旧版typing_utils的类型归一化逻辑正确识别,递归解析类型参数时,会将Literal包裹的字符串字面量(如示例中的"train")误判为可迭代的类型序列,无限递归调用_normalize_args方法,最终超出Python最大递归深度触发报错。
  • 该bug仅存在于Python < 3.9 + 旧版本overrides/typing_utils的组合环境中,新版依赖已经修复了该类型解析逻辑。
可行解决方案
  • 升级依赖版本:将overrides升级至6.1.0及以上版本,同步升级配套的typing_utils至0.1.0及以上版本,新版本已修复Literal类型的递归解析问题,可直接正常使用。
  • 临时关闭签名检查:如果暂时无法升级依赖,可使用@overrides(check_signature=False)写法,既保留装饰器的重写标记作用,也不会触发类型校验逻辑的bug。
  • 替换类型实现:按照原计划将Literal类型替换为Enum实现,该方案在类型设计上更严谨,也可完全规避该解析bug。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 10:06:20