mypy 找不到模块的实现或库存根

Tom*_*tse 43 python mypy

我有:

\n
foo/\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __init__.py\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 bar.py\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 baz\n    \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __init__.py\n    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 alice.py\n
Run Code Online (Sandbox Code Playgroud)\n

在 中bar.py,我导入 Alice,它是一个空类,除了name属性设置为之外什么都没有"Alice"

\n
from baz.alice import Alice\n\na = Alice()\nprint(a.name)\n
Run Code Online (Sandbox Code Playgroud)\n

这可以正常运行:

\n
$ python foo/bar.py\nAlice\n
Run Code Online (Sandbox Code Playgroud)\n

但 mypy 抱怨道:

\n
$ mypy --version\nmypy 0.910\n$ mypy --strict .\nfoo/bar.py:1: error: Cannot find implementation or library stub for module named "baz.alice"\nfoo/bar.py:1: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports\nFound 1 error in 1 file (checked 6 source files)\n
Run Code Online (Sandbox Code Playgroud)\n

为什么 mypy 会抱怨?

\n

Yu *_*hen 37

mypy 有自己的导入搜索路径,并且不能像 Python 那样完全解析导入,并且无法找到该baz.alice模块。检查错误消息中列出的文档,特别是有关如何找到导入的部分:

\n
\n

搜索模块的规则foo如下:

\n

搜索将在搜索路径中的每个目录中查找(参见上文),直到找到匹配项。

\n
    \n
  1. 如果找到名为的包foo(即包含__init__.py__init__.pyi文件的目录 foo),则 \xe2\x80\x99 匹配。
  2. \n
  3. 如果找到名为的存根文件foo.pyi,则 \xe2\x80\x99 匹配。
  4. \n
  5. 如果找到名为的 Python 模块foo.py,则 \xe2\x80\x99 匹配。
  6. \n
\n
\n

该文档还在“将文件路径映射到模块”部分中指出:

\n
\n

对于要检查的每个文件,mypy将尝试将文件\n(例如project/foo/bar/baz.py)与完全限定的模块名称(例如\n foo.bar.baz)相关联。

\n
\n

有几种方法可以解决这个特定问题:

\n
    \n
  1. 正如 paul41 在他的评论中提到的,解决此问题的一个选择是提供完全限定的导入 ( from foo.baz.alice import Alice),然后从顶级模块(.py根级别中的文件)运行。
  2. \n
  3. 您可以将 a 添加# type: ignore到导入行。
  4. \n
  5. 您可以编辑MYPYPATH变量以指向foo目录:
  6. \n
\n
(venv) (base) \xe2\x9e\x9c mypy foo/bar.py --strict\nfoo/bar.py:3: error: Cannot find implementation or library stub for module named "baz.alice"\nfoo/bar.py:3: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports\nFound 1 error in 1 file (checked 1 source file)\n(venv) (base) \xe2\x9e\x9c export MYPYPATH=foo/     \n(venv) (base) \xe2\x9e\x9c mypy foo/bar.py --strict\nSuccess: no issues found in 1 source file\n
Run Code Online (Sandbox Code Playgroud)\n

  • @TomHuibregtse 是的,我只是为您提供解决错误的方法。理想情况下,除非确实必须,否则您不想禁用特定行的 mypy 类型检查。 (3认同)
  • 如果我仍然想对“foo.bar”中“foo.baz.alice”模块的使用进行类型检查,那么使用“# type:ignore”不是不需要的吗?另外,我喜欢上面的“PYTHONPATH”解决方案。它允许我使用完全限定的模块名称。Poetry 负责将“foo/”添加到“PYTHONPATH”,如“sys.path”输出所示。 (2认同)