简体   繁体   中英

How to override a method that has an argument of type Literal?

When I try to override a method that has an argument with Literal as its type hint, I get a RecursionError from the overrides module (see stack trace below). I'm not sure why this is happening, or if it is possible to override such methods.

edit: The overrides module I'm talking about is this third party module: github.com/mkorpela/overrides

Here is a toy example that reproduces my error:

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

Removing the @overrides decorator is a workaround since it doesn't change my code's behavior, but I would prefer to keep it if possible. My plan is to change the arg type to an Enum which is probably a better design decision anyway. But I'm curious why this combination of @overrides and Literal doesn't work.

Here is the stack trace:

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

As others have noted in the comments, this behavior is a bug in the third party overrides module I'm using https://github.com/mkorpela/overrides ). It is a known bug: https://github.com/mkorpela/overrides/issues/94

Bug in the package is now fixed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM