Python 3 的类型检查工具

Type checking tool for Python 3

我正在尝试 运行 一个命令,该命令在作为目录提供的某些 Python 源代码中提供有关类型检查、静态代码分析等的一些汇总信息。如果存在这样的东西,那么我想将它添加到 Makefile 在某些 CI 管道期间调用以验证代码库。

我创建了这个带有运行时间问题

的虚拟源代码文件

文件foo_sample.py

def foo_func(my_num):
    return 1 + my_num


def bar_func():
    foo_func("foo")


if __name__ == "__main__":
    bar_func()

它抛出这个 运行时间错误:

TypeError: unsupported operand type(s) for +: 'int' and 'str'.

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

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

有没有办法在 运行 代码本身之前 运行 这些类型的检查?

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

未声明的类型被认为是 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 and warn_return_any. Example configuration

我发现 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

在文档中查看如何使用这些注释,Error classes