使用不带类型注释的 mypy 检测类型错误
Detecting type errors using mypy without type annotations
以下脚本包含故意的类型错误:
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"
是否可以在没有任何手动类型注释的情况下找到这样的错误?
这在 mypy 中是不可能的。 Mypy 遵循 PEP 484 语义,即如果函数的参数未注释,则假定它们具有 Any
类型,表示未知类型的完全动态值。
这个设计决定是有意为之的。这部分是因为进行整个程序类型推断具有挑战性,尤其是当您允许对象、子类型、可变性等时:要求用户在 "boundary" 处修复类型有助于使类型提示易于处理。
这在一定程度上也是为了帮助确保向后兼容性。类型提示是有意设计的,以便可以以有意义的方式将非类型化和动态代码与类型化代码混合。如果您想将类型提示引入现有项目,这将特别有用:默认情况下,所有内容都保证被视为动态类型,这使您可以慢慢添加类型而不会被错误淹没。 (至少这是梦想——我不认为 mypy 不会完全让你这样做。)
也就是说, 一些人正在尝试实现整个程序的类型推断——例如,参见 pytype 项目。但是,我的理解是它仍处于 alpha 阶段。
以下脚本包含故意的类型错误:
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"
是否可以在没有任何手动类型注释的情况下找到这样的错误?
这在 mypy 中是不可能的。 Mypy 遵循 PEP 484 语义,即如果函数的参数未注释,则假定它们具有 Any
类型,表示未知类型的完全动态值。
这个设计决定是有意为之的。这部分是因为进行整个程序类型推断具有挑战性,尤其是当您允许对象、子类型、可变性等时:要求用户在 "boundary" 处修复类型有助于使类型提示易于处理。
这在一定程度上也是为了帮助确保向后兼容性。类型提示是有意设计的,以便可以以有意义的方式将非类型化和动态代码与类型化代码混合。如果您想将类型提示引入现有项目,这将特别有用:默认情况下,所有内容都保证被视为动态类型,这使您可以慢慢添加类型而不会被错误淹没。 (至少这是梦想——我不认为 mypy 不会完全让你这样做。)
也就是说, 一些人正在尝试实现整个程序的类型推断——例如,参见 pytype 项目。但是,我的理解是它仍处于 alpha 阶段。