满足pylint和mypy的要求,需要一个 __init__.py 文件吗?

6

我有一个包含以下(部分)目录结构的项目

.
├── mypy.ini
├── src
│   ├── preppy
│   │   ├── cli.py
│   │   ├── __main__.py
│   │   ├── model.py
│   │   └── tools.py
├── pyproject.toml
└── tests

在文件cli.py中,我有以下代码(文件中的第13行和第14行):
from .model import Problem
from .tools import get_abs_path, transcode

我在model.py__main__.py中也有类似的相对导入。所有相似的导入都会在我的IDE(Code-OSS)自动运行工具(如pylint(2.5.3)和mypy(0.761))中抛出错误。

Attempted relative import beyond top-level package pylint(relative-beyond-top-level) [13,1]
Cannot find implementation or library stub for module named '.model' mypy(error) [13,1]
Attempted relative import beyond top-level package pylint(relative-beyond-top-level) [14,1]
Cannot find implementation or library stub for module named '.tools' mypy(error) [14,1]
See https://mypy.readthedocs.io/en/latest/running_mypy.html#missing-imports mypy(note) [13,1]

当我向文件夹中添加一个空白的__init__.py文件时,错误消失了。 我不需要这个__init__.py文件让包正常工作。 我认为在PEP 420之后,它不应该是必需的,特别是如果只是为了满足 lint 程序的要求。
我是否还有其他做错的地方,或者只需要添加__init__.py并解决它 :) ? pylint 的配置位于pyproject.toml中:
[tool.pylint.'MESSAGES CONTROL']
# Pylint and black disagree on hanging indentation.
disable = "C0330"

[tool.pylint.MISCELLANEOUS]
# Note: By default, "TODO" is flagged, this is disabled by omitting it
#       from the list below.
notes = "FIXME,XXX"

mypy 的配置在 mypy.ini 文件中:

[mypy]
disallow_untyped_calls = True
disallow_untyped_defs = True
disallow_incomplete_defs = True
disallow_untyped_decorators = True
mypy_path = src
namespace_packages = True

[mypy-openpyxl]
ignore_missing_imports = True

[mypy-pulp]
ignore_missing_imports = True

[mypy-pytest]
ignore_missing_imports = True

我正在运行Python 3.8.0。


2
请注意,PEP 420并没有说“您可以通过省略__init__.py来创建一个包”,它说的是“您可以通过省略__init__.py来创建一个命名空间包”。那么您想要一个包还是想要一个命名空间包? - MisterMiyagi
@MisterMiyagi 您说得很对,我并不明确想要一个命名空间包 - 我只是试图减少文件混乱。也许最好还是加上 __init__.py - multipitch
2个回答

7

PEP 420不允许“通过省略__init__.py创建一个包”,而是强制要求“通过省略__init__.py创建命名空间包”。这意味着:

  • 如果您想要一个包,请添加__init__.py
  • 如果你想要一个命名空间包,请省略__init__.py

虽然像常规包一样使用命名空间包通常有效,但当包名称冲突时,它可能会意外失败。在大多数情况下,不建议使用命名空间包。


它“可能在包名冲突时意外失败”?你能详细解释一下吗? - Ray

2
对于mypy,作为被接受答案的替代方法是使用mypy选项--namespace-packages,以便mypy可以考虑命名空间包。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接