Pytype 检查并推断 Python 代码的类型 - 无需类型注释。 Pytype 可以:
Pytype是一个静态分析器;它不执行它所运行的代码。
Google 的数千个项目都依赖 pytype 来保持其 Python 代码类型正确且无错误。
有关更多信息,请查看用户指南、常见问题解答或支持的功能。
Pytype 使用推理而不是逐步打字。这意味着即使代码没有类型提示,它也会推断代码的类型。因此它可以检测这样的代码问题,而其他类型检查器会错过这些问题:
def f ():
return "PyCon"
def g ():
return f () + 2019
# pytype: line 4, in g: unsupported operand type(s) for +: 'str'
# and 'int' [unsupported-operands]
Pytype 是宽松的而不是严格的。这意味着它允许所有操作在运行时成功并且不与注释相矛盾。例如,此代码在 pytype 中将安全通过,但在其他类型检查器中失败,这些类型检查器在变量初始化后立即将类型分配给变量:
from typing import List
def get_list () -> List [ str ]:
lst = [ "PyCon" ]
lst . append ( 2019 )
return [ str ( x ) for x in lst ]
# mypy: line 4: error: Argument 1 to "append" of "list" has
# incompatible type "int"; expected "str"
另请参阅相应的常见问题解答条目。
要快速开始对文件或目录进行类型检查,请运行以下命令,并将file_or_directory
替换为您的输入:
pip install pytype
pytype file_or_directory
要在整个包上设置 pytype,请将以下内容添加到包上方目录中的pyproject.toml
文件中,并将package_name
替换为包名称:
[ tool . pytype ]
inputs = [ ' package_name ' ]
现在您可以运行无参数命令pytype
对包进行类型检查。将 pytype 添加到自动化测试中也很容易;请参阅在 GitHub Actions 上运行 pytype 的 GitHub 项目示例。
最后, pytype 生成推断类型信息的文件,默认位于.pytype/pyi
中。您可以使用此信息对相应的源文件进行类型注释:
merge-pyi -i < filepath > .py .pytype/pyi/ < filename > .pyi
您需要一个 Python 3.8-3.12 解释器来运行 pytype,以及$PATH
中用于您正在分析的代码的 Python 版本的解释器(支持:3.8-3.12)。
平台支持:
* 在 Alpine Linux 上,安装可能会由于上游依赖项问题而失败。请参阅此问题的详细信息以获取可能的解决方案。
** 如果 ninja 依赖项安装失败,请确保 cmake 已安装。详情请参阅本期。
Pytype 可以通过 pip 安装。请注意,安装需要wheel
和setuptools
。 (如果您在 virtualenv 中工作,这两个包应该已经存在。)
pip install pytype
或者来自 GitHub 上的源代码。
git clone --recurse-submodules https://github.com/google/pytype.git
cd pytype
pip install .
您也可以运行而不是使用--recurse-submodules
git submodule init
git submodule update
在pytype
目录中。要编辑代码并实时跟踪您的编辑,请将 pip install 命令替换为:
pip install -e .
按照上述步骤操作,但首先确保您拥有正确的库:
sudo apt install build-essential python3-dev libpython3-dev
usage: pytype [options] input [input ...]
positional arguments:
input file or directory to process
常用选项:
-V, --python-version
:目标代码的Python版本(主要.次要)。默认为 pytype 运行时的版本。-o, --output
:所有 pytype 输出所在的目录,包括生成的 .pyi 文件。默认为.pytype
。-d, --disable
。要忽略的错误名称的逗号或空格分隔列表。 pytype 错误名称的详细解释在此文档中。默认为空。有关选项的完整列表,请运行pytype --help
。
除了上述之外,您还可以通过设置$TYPESHED_HOME
来指示 pytype 使用自定义 typeshed 安装,而不是其自己的捆绑副本。
为了方便起见,您可以将 pytype 配置保存在文件中。配置文件可以是带有[tool.pytype]
部分(首选)的 TOML 样式文件,也可以是带有[pytype]
部分的 INI 样式文件。如果未提供显式配置文件,pytype 将从当前工作目录向上查找,在第一个pyproject.toml
或setup.cfg
文件中查找 pytype 部分。
首先生成一个示例配置文件:
$ pytype --generate-config pytype.toml
现在根据您的本地设置自定义文件,仅保留您需要的部分。目录可能与配置文件的位置相关,如果您想将配置文件作为项目的一部分签入,这很有用。
例如,假设您有以下目录结构并想要分析包~/repo1/foo
,它依赖于包~/repo2/bar
:
~/
├── repo1
│ └── foo
│ ├── __init__.py
│ └── file_to_check.py
└── repo2
└── bar
├── __init__.py
└── dependency.py
下面是填写的配置文件,它指示 pytype 将~/repo1/foo
作为 Python 3.9 代码进行类型检查,在~/repo1
和~/repo2
中查找包,并忽略属性错误。请注意,包的路径不包括包本身。
$ cat ~/repo1/pytype.toml
# NOTE: All relative paths are relative to the location of this file.
[ tool . pytype ]
# Space-separated list of files or directories to process.
inputs = [
' foo ' ,
]
# Python version (major.minor) of the target code.
python_version = ' 3.9 '
# Paths to source code directories, separated by ':'.
pythonpath = . :~/repo2
# Space-separated list of error names to ignore.
disable = [
' attribute-error ' ,
]
我们可能已经发现~/repo2
需要通过运行 pytype 的损坏依赖检查器添加到 pythonpath 中:
$ pytype --config=~/repo1/pytype.toml ~/repo1/foo/*.py --unresolved
Unresolved dependencies:
bar.dependency
除了pytype
本身之外,Pytype 还附带了一些脚本:
annotate-ast
,一个正在进行的 AST 类型注释器。merge-pyi
,用于将 .pyi 文件中的类型信息合并到 Python 文件中。pytd-tool
,.pyi 文件的解析器。pytype-single
是 pytype 开发人员的调试工具,它分析单个 Python 文件,假设已经为其所有依赖项生成了 .pyi 文件。pyxref
,交叉引用生成器。 阿帕奇2.0
这不是 Google 官方产品。