pyannotate-自动生成PEP-484注释的python库
对于静态检查Python代码,mypy很棒,但是只有在将类型注释添加到代码库后,它才有效。当您拥有大型代码库时,这可能会很痛苦。在Dropbox,我们注释了超过120万行代码(约占我们Python代码库总数的20%),因此我们知道这可以做多少工作。但这是值得的:回报是惊人的。
为了减轻在现有代码中添加类型注释的麻烦,我们开发了一个工具PyAnnotate,它观察运行时实际使用的类型,并根据这些观察结果将注释插入源代码中。现在,我们对该工具进行了开源。
运作方式如下。首先,您需要启用一个特殊的分析钩子来运行代码。这将观察所有调用参数和返回值,并将观察到的类型记录在内存中。运行结束时,数据将以JSON格式转储到文件中。然后,一个单独的命令行实用程序可以读取此JSON文件,并使用它向源代码添加内联注释。
添加自动注释后,您应该在更新的文件上运行mypy,以验证生成的注释是否有意义,并且很可能您将不得不手动调整一些注释。但是一旦掌握了这一点,PyAnnotate便可以在将注释添加到大型代码库时为您节省很多工作,这没什么可打扰的。
PyAnnotate旨在EAS è添加类型注释到现有的工作(可以说“传统”)的代码。对于新代码,我们建议您在编写代码时添加注释-类型注释应反映作者的意图,并且没有比最初编写代码时更好的时间来捕获这些意图。
在哪里获取PyAnnotate
PyAnnotate的完整源代码在GitHub上,包括详细的使用文档,如果您只想下载它的源代码,也可以从网盘上面下载PyAnnotate。
示例
这是一个定义gcd()函数并调用几次的小程序:
# gcd.py
def main():
print(gcd(15, 10))
print(gcd(45, 12))
def gcd(a, b):
while b:
a, b = b, a%b
return a
我们还需要一个驱动程序脚本:
# driver.py
from gcd import main
from pyannotate_runtime import collect_types
if __name__ == '__main__':
collect_types.init_types_collection()
with collect_types.collect():
main()
collect_types.dump_stats('type_info.json')
现在,让我们安装PyAnnotate并运行驱动程序脚本。标准输出就是main()函数输出的内容:
$ pip install pyannotate
$ python driver.py
5
3
$
此时,如果您好奇,可以查看type_info.json查看记录的类型:
[
{
"path": "gcd.py",
"line": 1,
"func_name": "main",
"type_comments": [
"() -> None"
],
"samples": 1
},
{
"path": "gcd.py",
"line": 5,
"func_name": "gcd",
"type_comments": [
"(int, int) -> int"
],
"samples": 2
}
]
让我们继续注释gcd.py文件(在-w标志的手段“去进取,更新文件”):
$ pyannotate -w gcd.py
Refactored gcd.py
--- gcd.py (original)
+++ gcd.py (refactored)
@@ -1,8 +1,10 @@
def main():
+ # type: () -> None
print(gcd(15, 10))
print(gcd(45, 12))
def gcd(a, b):
+ # type: (int, int) -> int
while b:
a, b = b, a%b
return a
Files that were modified:
gcd.py
$ mypy gcd.py
$
由于原始文件非常小,因此PyAnnotate打印的统一差异仅显示整个文件。请注意,最后一条命令显示mypy对结果感到满意!如果您不想看到diff输出,请使用-q标志。