【问题标题】:How to override a method that has an argument of type Literal?如何覆盖具有 Literal 类型参数的方法?
【发布时间】:2022-08-05 12:39:11
【问题描述】:

当我尝试覆盖一个以Literal 作为其类型提示的参数的方法时,我从overrides 模块中得到一个RecursionError(参见下面的堆栈跟踪)。我不确定为什么会发生这种情况,或者是否可以覆盖这些方法。

编辑:我正在谈论的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 装饰器是一种解决方法,因为它不会改变我的代码的行为,但如果可能的话,我更愿意保留它。我的计划是将 arg 类型更改为 Enum,这可能是一个更好的设计决策。但我很好奇为什么@overridesLiteral 的这种组合不起作用。

这是堆栈跟踪:

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

标签: python types overriding literals


【解决方案1】:

正如其他人在 cmets 中指出的那样,这种行为是我正在使用的第三方 overrides 模块中的一个错误 https://github.com/mkorpela/overrides)。这是一个已知的错误:https://github.com/mkorpela/overrides/issues/94

【讨论】:

    【解决方案2】:

    包中的错误现已修复。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-02-28
      • 1970-01-01
      • 1970-01-01
      • 2012-08-25
      • 2020-07-16
      • 1970-01-01
      • 2014-08-11
      相关资源
      最近更新 更多