微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

尽管 mypy 很高兴,但通用超类“未定义”

如何解决尽管 mypy 很高兴,但通用超类“未定义”

我一直在为奇怪的情况而苦苦挣扎,其中 mypy 很高兴,但是当我运行代码时,python 崩溃了。这是我在使用泛型时遇到的一个问题。我在同一个目录中有两个文件。当我在 sample_parser.py 中运行 python3 时,出现以下错误

Traceback (most recent call last):
  File "/Users/joe/repos/ut-norm-james/so_generics/sample_parser.py",line 8,in <module>
    class SampleParser(LookaheadParser[str]):
NameError: name 'LookaheadParser' is not defined

这是lookahead_parser.py

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from typing import TypeVar,Generic,Optional,Callable


_T = TypeVar("_T")
StateFunc = Callable[[_T],Callable]


class LookaheadParser(Generic[_T]):
    def __init__(self):
        self._token_index: int = 0
        self._tokens: list[_T] = []
        self._state: StateFunc

    def _parse(self) -> None:
        while self._token_index < len(self._tokens):
            self._state = self._state(self._tokens[self._token_index])
            self._token_index += 1

    def _lookahead(self,offset: int) -> Optional[_T]:
        prospective_index = self._token_index + offset
        if prospective_index < len(self._tokens):
            return self._tokens[prospective_index]
        return None

    def _advance(self,offset: int) -> None:
        self._token_index += offset

这是sample_parser.py

from __future__ import annotations
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from .lookahead_parser import LookaheadParser,StateFunc


class SampleParser(LookaheadParser[str]):
    def __init__(self,raw_text: str):
        self._raw_text = raw_text
        self._state = self._state_first

    def parse(self) -> None:
        self._parse()

    def _state_first(self,token: str) -> StateFunc:
        pass  # stub


if __name__ == "__main__":
    pass  # stub

我正在运行 Python 3.9.6,但它也在 3.9.5 中发生。无论我使用 _T 还是 T,都会出现问题,以防您对此产生怀疑。 mypy 本身没有报告任何问题。

解决方法

只有在 lookahead_parser 为真时才导入 TYPE_CHECKING。该变量在运行时为 false,因此模块永远不会被加载。只需删除 if TYPE_CHECKING: 部分并无条件地进行导入。

from .lookahead_parser import LookaheadParser,StateFunc

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。