Python 3 的类型检查工具

问题描述 投票:0回答:2

我正在尝试运行一个命令,该命令在作为目录提供的一些 Python 源代码中提供有关类型检查、静态代码分析等的一些聚合信息。如果存在这样的东西,那么我想将其添加到在某些

CI
管道期间调用的 Makefile 以验证代码库。

我创建了这个虚拟源代码文件,但存在运行时问题

文件foo_sample.py

def foo_func(my_num):
    return 1 + my_num


def bar_func():
    foo_func("foo")


if __name__ == "__main__":
    bar_func()

它抛出此运行时错误:

类型错误:+ 不支持的操作数类型:“int”和“str”。

现在我尝试使用各种工具来检测这种类型的错误,但它们都未能发现此类问题。请参阅以下列表中的命令:

  • pyflakes foo_sample.py
    ,
  • flake8 foo_sample.py
    ,
  • pylint foo_sample.py
    ,
  • mypy --check-untyped-defs foo_sample.py
    ,
  • prospector --strictness veryhigh foo_sample.py

我知道我可以使用

unittest
检测这些问题,但代码库相当大并且在某种程度上未经测试。我们经常看到运行时错误,并通过单元测试或集成测试来解决它们。然而,我们希望在 CI 管道的执行过程中检测到它们。

有没有办法在运行代码本身之前运行此类检查?

如何避免在运行时发现这些错误?

python python-typing mypy pylint
2个回答
3
投票

未声明的类型被认为是

Any
类型,并且不由
mypy
进行类型检查。需要更严格的配置来确保
mypy
强制您设置类型。具体来说,您需要
disallow_untyped_defs
,这应该会导致您得到以下结果:

$ cat test.py 
def foo_func(my_num: int) -> int:
    return 1 + my_num


def bar_func() -> None:
    foo_func("foo")


if __name__ == "__main__":
    bar_func()
$ mypy test.py
test.py:6: error: Argument 1 to "foo_func" has incompatible type "str"; expected "int"
Found 1 error in 1 file (checked 1 source file)

您可能还想要

disallow_any_generics
warn_return_any
配置示例


2
投票

我发现 pytype 在这种情况下很有用。

在此代码上调用

pytype broken_code.py
时:

def foo_func(my_num):
    return 1 + my_num


def bar_func():
    foo_func("foo")

def run_func(my_func):
    my_func()


if __name__ == "__main__":
    bar_func()
    run_func(bar_func())

我在输出中正确找到:

  • line 3, in foo_func: unsupported operand type(s) for +: 'int' and 'str' [unsupported-operands]
  • line 10, in run_func: 'NoneType' object is not callable [not-callable]

命令退出时出现错误,因此

Makefile
调用它可能会阻止 CI 环境中管道的执行。

此外,可以通过代码中的注释启用或禁用那些错误检查,例如

[unsupported-operands]
等,例如,

  • 首先禁用检查
    # pytype: disable=attribute-error
  • 然后再次启用检查
    # pytype: enable=attribute-error

请参阅文档中如何使用这些注释,错误类

© www.soinside.com 2019 - 2024. All rights reserved.