当我重构代码时,我经常发现自己在枯燥地添加从上下文中显而易见的类型注解:不返回任何内容的函数、布尔标志等。这就是自动类型化的用武之地:它会自动添加这些类型并插入正确的注解。
使用方法
以下是使用方法:
pip install autotyping
python -m autotyping /path/to/my/code
默认情况下它不执行任何操作;你需要添加标志来使其执行更多转换。支持以下操作:
- 注解返回类型:
--none-return
:为主体中没有任何return、yield或raise的函数添加-> None
返回类型--scalar-return
:为只返回字面量bool、str、bytes、int或float对象的函数添加返回注解
- 注解参数类型:
--bool-param
:为默认值为True
或False
的任何函数参数添加: bool
注解--int-param
、--float-param
、--str-param
、--bytes-param
:为默认值为字面量int、float、str或bytes对象的任何参数添加注解--annotate-optional foo:bar.Baz
:对于形如foo=None
的任何参数,添加从bar
导入的Baz
作为类型。例如,使用--annotate-optional uid:my_types.Uid
可以将代码库中任何默认值为None
的uid
注解为Optional[my_types.Uid]
--annotate-named-param foo:bar.Baz
:为任何没有默认值且名为foo
的参数添加bar.Baz
注解。例如,使用--annotate-named-param uid:my_types.Uid
可以将代码库中任何没有默认值的uid
参数注解为my_types.Uid
--guess-common-names
:根据开源Python代码中的常见模式,推断某些参数类型。例如,推断verbose
参数的类型为bool
- 注解魔术方法:
--annotate-magics
:为某些魔术方法添加类型注解。目前包括以下内容:__str__
返回str
__repr__
返回str
__len__
返回int
__length_hint__
返回int
__init__
返回None
__del__
返回None
__bool__
返回bool
__bytes__
返回bytes
__format__
返回str
__contains__
返回bool
__complex__
返回complex
__int__
返回int
__float__
返回float
__index__
返回int
__exit__
:三个参数分别为Optional[Type[BaseException]]
、Optional[BaseException]
和Optional[TracebackType]
__aexit__
:与__exit__
相同
--annotate-imprecise-magics
:为一些额外的魔术方法添加不精确的类型注解。目前为__iter__
、__await__
和__reversed__
添加typing.Iterator
返回注解。这些注解应该有一个泛型参数来指明你在迭代什么,但这对自动类型化来说太难了
- 外部集成:
--pyanalyze-report
:采用pyanalyze的suggested_parameter_type
和suggested_return_type
代码建议的类型并应用它们。你可以使用类似这样的命令生成这些建议:pyanalyze --json-output failures.json -e suggested_return_type -e suggested_parameter_type -v .
--only-without-imports
:仅应用不需要新导入的pyanalyze建议。这很有用,因为需要导入的建议可能需要更多手动工作
有两个快捷标志可以同时启用多个转换:
--safe
启用应该始终安全的更改。这包括--none-return
、--scalar-return
和--annotate-magics
--aggressive
启用风险更高的更改,更有可能产生新的类型检查器错误。它包括--safe
的所有内容以及--bool-param
、--int-param
、--float-param
、--str-param
、--bytes-param
和--annotate-imprecise-magics
LibCST
Autotyping是作为LibCST codemod构建的;有关如何使用codemod的更多信息,请参阅LibCST文档。
如果你希望通过libcst.tool
接口运行,可以这样做:
- 确保你有一个
.libcst.codemod.yaml
文件,其中modules
列表包含'autotyping'
。 例子请参见此仓库中的.libcst.codemod.yaml
。 - 运行
python -m libcst.tool codemod autotyping.AutotypeCommand /path/to/my/code
局限性
Autotyping旨在成为一个简单的工具,使用启发式方法找到手动添加会很繁琐的注解。这些启发式方法可能会失败,在运行autotyping后,你应该运行类型检查器来验证它添加的类型是否正确。
已知局限性:
- autotyping不模拟函数内的代码流,所以它可能会遗漏隐式的
None
返回
更新日志
24.3.0(2024年3月25日)
- 添加更简单的调用autotyping的方式。现在可以简单地使用
python3 -m autotyping
来调用该工具。(感谢Shantanu Jain。) - 停止支持Python 3.7;添加对Python 3.12的支持。(感谢Hugo van Kemenade。)
- 为一些更多的魔术方法推断返回类型。(感谢Dhruv Manilawala。)
23.3.0(2023年3月3日)
- 修复了某些参数名称(如
iterables
)导致的崩溃(由Marco Gorelli贡献)
23.2.0(2023年2月3日)
- 添加
--guess-common-names
(由John Litborn贡献) - 修复
--safe
和--aggressive
标志,使它们不接受被忽略的参数 --length-hint
应该返回int
(由Nikita Sobolev贡献)- 修复导入添加的错误(由Shantanu贡献)
22.9.0(2022年9月5日)
- 添加
--safe
和--aggressive
- 添加
--pyanalyze-report
- 不为标记有
@abstractmethod
的方法和存根文件中的方法添加None
返回类型 - 改进类型推断:
"string" % ...
总是str
b"bytes" % ...
总是bytes
- 左右两侧类型相同的
and
或or
运算符返回该类型 is
、is not
、in
和not in
总是返回bool
21.12.0(2021年12月21日)
- 首次PyPI发布