自动生成Python类型注释?

Mar*_*son 6 python types type-hinting

我正在改装一些旧的Python代码以添加PyType注释。我通过将打印语句添加到每个函数的顶部来机械地进行此操作

def f(a, b):
    print("type a:", type(a))
    print("type b:", type(b))
Run Code Online (Sandbox Code Playgroud)

并进行相应的更新。

有什么可以帮助自动化该过程的吗?

Mar*_*ers 12

当然,有一些项目可以提供帮助。

  • Instagram开发了该MonkeyType工具来获取运行时类型信息。这些作为存根文件输出,但是您可以使用附带的工具将这些内容作为内联注释应用到您的源文件中,或者使用retype项目执行相同的操作。
  • Dropbox有一个类似的工具,称为pyannotate;该工具可以生成Python 2类型的提示注释或注释。

这两个项目都不会产生完美的类型提示。始终将其输出作为起点,而不是权威性的最终注释。引用MonkeyType自述文件:

使用MonkeyType,添加注释以反映您在运行时使用的具体类型非常容易,但是这些注释可能并不总是与功能的全部预期功能匹配。例如,add不仅可以处理整数,还可以处理更多类型。类似地,MonkeyType可能会生成一个具体的List注释,其中抽象Sequence或Iterable更合适。MonkeyType的注释是内容丰富的初稿,将由开发人员进行检查和更正。

但是请阅读有关Instagram工程博客的文章MonkeyType ; 它有助于在Instagram代码库中添加类型注释。

免责声明:MonkeyType和retype都是Facebook同事的项目。我自己对这些工具没有任何投入。

  • 这是完美的,并且很好地提醒我们输出(就像我的打印语句一样)只是一个很好的起点。 (2认同)
  • 您认为 MonkeyType 和 pyannotate 哪一个效果更好? (2认同)

a.t*_*.t. 5

我发现给定的答案有点抽象,所以这是我在具有以下结构的项目上验证的具体(复制粘贴)解决方案:

projectname/
|-- src/
|   |-- projectname/__main__.py
|   |-- projectname/some_folder/some_script.py
|-- tests/
|   |-- projectname/test_something.py
|   |-- projectname/another_folder/test_another_thing.py
|
|-- setup.py
|-- README.md
Run Code Online (Sandbox Code Playgroud)

主要代码执行如下:

python -m src.projectname
Run Code Online (Sandbox Code Playgroud)

测试是通过以下方式执行的:

python -m pytest
Run Code Online (Sandbox Code Playgroud)

描述

该解决方案使用现有的测试tests来生成存根。它使用pyannotateDropbox 的项目。

局限性

  1. 它只为测试使用/调用的函数生成存根。
  2. 我还没有找到如何type-hints为 调用的代码生成src/projectname/__main__.py,但这似乎也是可能的。

1. 生成类型提示

生成一个.py接管运行测试的文件,以确保type-hints生成测试。

复制粘贴:

projectname/
|-- src/
|   |-- projectname/__main__.py
|   |-- projectname/some_folder/some_script.py
|-- tests/
|   |-- projectname/test_something.py
|   |-- projectname/another_folder/test_another_thing.py
|
|-- setup.py
|-- README.md
Run Code Online (Sandbox Code Playgroud)

进入tests/conftest.py

2. 生成类型提示。

跑步:

pip install pyannotate
python -m pytest
Run Code Online (Sandbox Code Playgroud)

这应该type_info.json在项目的根目录中输出一个名为:的文件。该文件包含type-hints.

3. 将类型提示应用到您的代码中

跑步:

for f in $(find src/ -name '*.py'); do pyannotate -w --python-version 3 --type-info type_info.json $f; done
for f in $(find tests/ -name '*.py'); do pyannotate -w --python-version 3 --type-info type_info.json $f; done
Run Code Online (Sandbox Code Playgroud)

这应该将类型提示应用于代码。您可以通过以下方式验证更改:

git diff
Run Code Online (Sandbox Code Playgroud)