使用mypy检测类型错误,不带类型注释

时间:2018-04-25 11:57:22

标签: python python-3.x types typechecking mypy

以下脚本包含故意类型错误:

def foo(x, y):
    print(x[:y])

def main():
    foo('abcde', '2')

if __name__ == "__main__":
    main()

错误可以通过运行来确认:

$ python3 untyped_test.py 
Traceback (most recent call last):
  File "untyped_test.py", line 8, in <module>
    main()
  File "untyped_test.py", line 5, in main
    foo('abcde', '2')
  File "untyped_test.py", line 2, in foo
    print(x[:y])
TypeError: slice indices must be integers or None or have an __index__ method

然而,我希望不仅在运行时,而且在使用以下代码执行代码之前捕获这样的东西:

mypy --check-untyped-defs untyped_test.py 

但它没有发现任何错误:

$ mypy --check-untyped-defs untyped_test.py 
$ mypy --version
mypy 0.590

仅当我注释foo时:

def foo(x: str, y: int):
    print(x[:y])

我明白了:

untyped_test.py:5: error: Argument 2 to "foo" has incompatible type "str"; expected "int"

是否可以在没有任何手动类型注释的情况下找到这样的错误?

1 个答案:

答案 0 :(得分:1)

这在mypy中是不可能的。 Mypy遵循PEP 484语义,该语义指出如果函数的参数未注释,则假定它们的类型为Any,表示未知类型的完全动态值。

此设计决定是有意的。这部分是因为进行整个程序类型推断具有挑战性,特别是一旦允许对象,子类型,可变性等等:要求用户在边界处修复类型&#34;有助于使类型提示易于处理。

这也有助于确保向后兼容性。有意设计类型提示,以便可以以有意义的方式将无类型和动态代码与类型化代码混合。如果要向现有项目引入类型提示,这将特别有用:默认情况下,所有内容都保证被视为动态类型,这使您可以慢慢添加类型而不会被错误所淹没。 (这至少是梦想 - 我不认为mypy不会让你这么做。)

也就是说, 某些人正在尝试实施整个程序类型的推理 - 例如,参见pytype项目。但是,我的理解是,它仍处于alpha阶段。