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

mypy Cannot find implementation or library stub for module

我有:

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

bar.py 中,我导入了 Alice,它是一个空的 class,里面除了 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 抱怨?

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

的部分

The rules for searching for a module foo are as follows:

The search looks in each of the directories in the search path (see above) until a match is found.

  1. If a package named foo is found (i.e. a directory foo containing an __init__.py or __init__.pyi file) that’s a match.
  2. If a stub file named foo.pyi is found, that’s a match.
  3. If a Python module named foo.py is found, that’s a match.

文档还在 Mapping file paths to modules 的部分中指出:

For each file to be checked, mypy will attempt to associate the file (e.g. project/foo/bar/baz.py) with a fully qualified module name (e.g. foo.bar.baz).

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

  1. 正如 paul41 在他的评论中提到的那样,解决这个问题的一个方法是提供完全限定的导入 (from foo.baz.alice import Alice),然后 运行 来自顶级模块 (a .py 文件在根级别)。
  2. 您可以在导入行中添加 # 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