使用 Mypy 本地存根

Using Mypy local stubs

我正在尝试 Python 3.5 引入的打字提示,但在使用本地存根作为 mypy 的打字提示时遇到了问题。

我做的实验是创建kk.py包含

def type_check(a):
    pass

此外,我把kk.pyi包含

def type_check(a: int):...

在同一目录中。就这样,我尝试通过给kk.py中的type_check传递一个字符串来触发"incompatible types in assignment"的错误。但是,当我 运行 mypy kk.py 时,我没有得到任何错误。

因此我尝试了mypy doc建议的另一种方法,即将环境变量MYPYPATH设置为~/some/path/stub并将kk.pyi放在目录中。我没有再收到任何错误。

任何人都可以帮助我吗?

这里是 how 上的 mypy wiki 以使用本地存根。

我不知道为什么有人没有回答或评论为什么 he/she 不喜欢它就否决了这个问题,但这是我想出的答案:

mypy的存根文件只在导入模块时有效。因此,如果您有

def try_check(a):
    pass

在 kk.py 和

def try_check(a: int):...

in kk.pyi 在与kk.py相同的目录下或者在MYPYPATH指定的目录下,如果你导入kk,mypy会类型检查python文件。 如果你有

import .kk
kk.try_check('str')

在test.py和运行mypytest.py中,mypy会报类型冲突。但是,如果你有

,它不会报告冲突
try_check('str')

在 kk.py.

您可以在包含函数定义的程序中键入检查函数,如果您在函数定义中显式编写键入提示。例如,你可以写

def try_check(a: int):
    pass

try_check('str')

在kk.py然后mypykk.py。 Mypy会报类型冲突。

正如提到的公认答案,不幸的是 Mypy 不使用 X.pyi 存根文件来对抗 X.py 本身,当你 运行 mypy X.py.

这里也解决了这个问题:
https://github.com/python/mypy/issues/5028

我发现检查模块本身的唯一解决方案是使用 mypy.stubtest:

A common problem with stub files is that they tend to diverge from the actual implementation. Mypy includes the stubtest tool that can automatically check for discrepancies between the stubs and the implementation at runtime.

用法很简单,就是运行 python -m mypy.stubtest X(X是没有.py扩展名的模块名)

示例:

$ python3 -m pip install mypy

$ cat library.py
x = "hello, stubtest"

def foo(x=None):
    print(x)

$ cat library.pyi
x: int

def foo(x: int) -> None: ...

$ python3 -m mypy.stubtest library
error: library.foo is inconsistent, runtime argument "x" has a default value but stub argument does not
Stub: at line 3
def (x: builtins.int)
Runtime: at line 3 in file ~/library.py
def (x=None)

error: library.x variable differs from runtime type Literal['hello, stubtest']
Stub: at line 1
builtins.int
Runtime:
hello, stubtest