首页 > 解决方案 > mypy 找不到模块的实现或库存根

问题描述

我有:

foo/
├── __init__.py
├── bar.py
└── baz
    ├── __init__.py
    └── alice.py

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

from baz.alice import Alice

a = Alice()
print(a.name)

这运行正常:

$ python foo/bar.py
Alice

但 mypy 抱怨:

$ mypy --version
mypy 0.910
$ mypy --strict .
foo/bar.py:1: error: Cannot find implementation or library stub for module named "baz.alice"
foo/bar.py:1: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports
Found 1 error in 1 file (checked 6 source files)

为什么 mypy 抱怨?

标签: pythonmypy

解决方案


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

查找模块的规则foo如下:

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

  1. 如果找到一个名为的包foo(即包含一个__init__.py__init__.pyi文件的目录 foo),那就是匹配的。
  2. 如果找到一个名为的存根文件foo.pyi,那就是匹配。
  3. 如果找到名为的 Python 模块foo.py,则匹配。

该文档还在将文件路径映射到模块的部分中指出了这一点:

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

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

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

推荐阅读