如何检查键入的存根(.pyi)文件是否与实现匹配?

时间:2018-08-06 21:59:27

标签: python typeshed python-typing

您可以使用mypy的stubgen.py或其他一些工具来generate .pyi files automatically,但是stubgen包含检查存根文件准确性的其他建议。

如果我自动生成了存根,然后对其进行了修改以修复错误或使生成器无法处理的事情变得更加严格,那么我如何检查它们是否与实现相符?还是随着实施方式的变化和我手工生成的文件,如何确保它们保持同步?

1 个答案:

答案 0 :(得分:1)

我发现这个问题是因为也需要这样做,所以这是我后来发现的......

Apparently, a tool called stubtest was recently added to mypy(目前未记录),它将尽可能根据实现验证存根。这是一个人为的例子:

$ cat <<EOF > simple.py
> def thing(obj):
>     if isinstance(obj, float):
>         return 0.0
>     elif isinstance(obj, int):
>         return 0
>     else:
>         raise TypeError("Unsupported type passed to thing.")
> 
> EOF

我创建了一个存根文件,它使用实现知识来编写特定的类型注释(绝对不是自动生成的 - 这很难做到!):

$ cat <<EOF > simple.pyi
> from typing import Any, Union
> 
> def thing(obj: Union[float, int]): ...
> 
> EOF

运行 stubtest 没有输出,并且退出代码为零:

$ python -m mypy.stubtest simple

$ echo $?
0

现在我更新实现以增加另一个参数:

cat <<EOF > simple.py
> def thing(obj, something_else):
>     if isinstance(obj, float):
>         return 0.0
>     elif isinstance(obj, int):
>         return 0
>     else:
>         raise TypeError("Unsupported type passed to thing.")
> 
> EOF

并重新运行存根测试:

$ python -m mypy.stubtest simple
error: simple.thing is inconsistent, stub does not have argument "something_else"
Stub: at line 3
def (obj: Union[builtins.float, builtins.int]) -> Any
Runtime: at line 1 in file stub-testing/simple.py
def (obj, something_else)

$ echo $?
1

我对 mypy 搜索路径的理解仍然相当薄弱,无法使直接的 stubtest 入口点起作用(与 python -m mypy.stubtest 形式相反)。

我还没有针对比这个玩具示例更复杂的任何东西进行测试 - 我怀疑细节中有很多问题。