为什么 mypy 检查我已排除的文件?

Edd*_*ian 23 python mypy

我正在尝试为项目设置 mypy 类型检查。我想从一开始就排除一堆文件/目录,这样我们至少可以强制对新代码进行类型检查,然后我们可以随着时间的推移烧掉排除列表。不幸的是 mypy 忽略了我的排除配置,我不明白为什么。

我创建了一个mypy.ini包含以下内容的配置文件:

[mypy]
python_version = 3.8
exclude = /examples/
Run Code Online (Sandbox Code Playgroud)

但是当我运行时mypy --verbose .,它仍然发现该目录中的文件存在错误。日志消息告诉我它看到了我的排除配置,但显然忽略了它:

LOG:  Mypy Version:           0.812
LOG:  Config File:            mypy.ini
LOG:  Configured Executable:  /Library/Developer/CommandLineTools/usr/bin/python
3
LOG:  Current Executable:     /Library/Developer/CommandLineTools/usr/bin/python
3
LOG:  Cache Dir:              .mypy_cache
LOG:  Compiled:               True
LOG:  Exclude:                /examples/
<snipped>
LOG:  Found source:           BuildSource(path='./examples/fib.py', module='fib', has_text=False, base_dir='/Users/user/a/examples')
LOG:  Found source:           BuildSource(path='./examples/fib_iter.py', module='fib_iter', has_text=False, base_dir='/Users/user/a/examples')
<snipped>
examples/fib.py: error: Duplicate module named 'fib' (also at './examples/a/fib.py')
examples/fib.py: note: Are you missing an __init__.py? Alternatively, consider using --exclude to avoid checking one of them.
Found 1 error in 1 file (errors prevented further checking)
Run Code Online (Sandbox Code Playgroud)

为什么我的排除配置不起作用?

ife*_*aju 23

就我而言,即使我正确排除了该文件夹,mypy 仍在检查它,因为它是在启用 mypy 的单独包中导入的。

假设我要排除的文件夹(也是一个包)名为examples. 要排除它,我需要将以下内容添加到文件mypy.ini

[mypy]
python_version = 3.8
exclude = examples/
Run Code Online (Sandbox Code Playgroud)

但这还不足以阻止 mypy 检查它,因为我有一个单独的包(允许 mypy 检查)导入该examples文件夹。

因此,为了解决这个问题,我还必须follow_imports = silent在 mypy.ini 文件中进行设置,如下所示:

[mypy-examples.*]
follow_imports = skip
Run Code Online (Sandbox Code Playgroud)

examples这将告诉 mypy每当发现包被导入到代码库中的其他位置时就跳过包的类型检查。


swe*_*zel 10

只是为像我这样使用预提交的人留下另一个答案mypy

我花了一段时间才意识到预提交将所有更改的文件明确作为参数发送到mypy,从而绕过了exclude设置,因为文件不是递归发现的。
因此,如果您想在预提交运行 mypy 时排除文件,您需要.pre-commit-config.yaml像这样设置排除(对于 django 项目):

- repo: https://github.com/pre-commit/mirrors-mypy
  rev: v1.0.0
  hooks:
  - id: mypy
    exclude: "/migrations/.*\\.py"
Run Code Online (Sandbox Code Playgroud)


Ber*_*rte 8

您不应该使用/examples/,而应该使用 或examples/examples因为第一个要求排除文件系统根目录的路径。同时,其他的声明一个本地路径,并且mypy可以将文件夹视为文件,因此您可以根据/需要省略该符号。

mypy.ini

[mypy]
python_version = 3.8
exclude = examples/
Run Code Online (Sandbox Code Playgroud)

如果你将mypy.ini文件更改为这个文件,它应该可以工作。