对 __init__.py 的要求只是为了满足 pylint 和 mypy

mul*_*tch 3 python pylint mypy

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

.
??? mypy.ini
??? src
?   ??? preppy
?   ?   ??? cli.py
?   ?   ??? __main__.py
?   ?   ??? model.py
?   ?   ??? tools.py
??? pyproject.toml
??? tests
Run Code Online (Sandbox Code Playgroud)

在 中cli.py,我有以下代码(文件中的第 13 和 14 行):

from .model import Problem
from .tools import get_abs_path, transcode
Run Code Online (Sandbox Code Playgroud)

我也有类似样式的相对导入,当工具在我的 IDE(代码 - OSS)中自动运行时model.py__main__.py 所有类似的导入都会在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]
Run Code Online (Sandbox Code Playgroud)

当我向__init__.py文件夹中添加一个空白文件时,错误就会消失。

我不需要这个__init__.py文件来让包工作。

我认为在 PEP 420 之后,它不应该是必需的,尤其是如果它只是为了满足短绒。

还有什么我做错了,还是我应该添加__init__.py并克服它:)?

配置pylintpyproject.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"
Run Code Online (Sandbox Code Playgroud)

配置mypymypy.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
Run Code Online (Sandbox Code Playgroud)

我正在运行 python 3.8.0。

Mis*_*agi 5

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

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

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