Pyanalyze是Python代码的半静态型检查器。像静态类型的检查器(例如,Mypy或Pyright)一样,它检测到代码中的类型错误,因此在到达生产之前可以找到错误。但是,与此类工具不同,它会导入其键入检查的模块,从而使Pyanalys可以理解其他类型的检查器会拒绝的许多动态结构。该属性还可以通过与代码直接交互的插件扩展pyanalyze。
您可以使用以下方式安装pyanalyze
$ pip install pyanalyze安装后,您可以在Python文件或软件包上运行pyanalyme,如下:
$ python -m pyanalyze file.py
$ python -m pyanalyze package/但是请注意,这将尝试导入它传递的所有Python文件。如果您的脚本可以执行操作,而if __name__ == "__main__":块,pyanalyze最终可能会执行它们。
为了成功运行,Pyanalyze需要能够导入其检查的代码。为了完成这项工作,您可能必须使用$PYTHONPATH环境变量手动调整Python的导入路径。
要快速实验,您还可以使用-c选项直接键入检查一件代码:
$ python -m pyanalyze -c 'import typing; typing.reveal_type(1)'
Runtime type is 'int'
Revealed type is 'Literal[1]' (code: reveal_type)
In <code> at line 1
1: import typing; typing.reveal_type(1)
^
Pyanalyze具有许多命令行选项,您可以通过运行python -m pyanalyze --help来看到它们。重要的包括-f ,它运行了交互式提示,可让您检查并修复pyanalyze和--enable / --disable发现的每个错误,从而启用和禁用特定的错误代码。
还支持通过pyproject.toml文件进行配置。有关详细信息,请参见文档。
扩展Pyanalyze的主要方法之一是为特定功能提供规范。这使您可以运行任意代码,该代码将参数检查到函数,并在出错时会引起错误。
例如,假设您的代码库包含一个函数database.run_query()该函数将作为参数作为sql字符串,诸如此类:
database . run_query ( "SELECT answer, question FROM content" )您要检测到run_query()的调用何时包含语法无效的SQL或涉及不存在的表或列。您可以使用这样的代码进行设置:
from pyanalyze . error_code import ErrorCode
from pyanalyze . signature import CallContext , Signature , SigParameter
from pyanalyze . value import KnownValue , TypedValue , AnyValue , AnySource , Value
from database import run_query , parse_sql
def run_query_impl ( ctx : CallContext ) -> Value :
sql = ctx . vars [ "sql" ]
if not isinstance ( sql , KnownValue ) or not isinstance ( sql . val , str ):
ctx . show_error (
"Argument to run_query() must be a string literal" ,
ErrorCode . incompatible_call ,
)
return AnyValue ( AnySource . error )
try :
parsed = parse_sql ( sql )
except ValueError as e :
ctx . show_error (
f"Invalid sql passed to run_query(): { e } " ,
ErrorCode . incompatible_call ,
)
return AnyValue ( AnySource . error )
# check that the parsed SQL is valid...
# pyanalyze will use this as the inferred return type for the function
return TypedValue ( list )
# in pyproject.toml, set:
# known_signatures = ["<module>.get_known_argspecs"]
def get_known_argspecs ( arg_spec_cache ):
return {
# This infers the parameter types and names from the function signature
run_query : arg_spec_cache . get_argspec (
run_query , impl = run_query_impl
),
# You can also write the signature manually
run_query : Signature . make (
[ SigParameter ( "sql" , annotation = TypedValue ( str ))],
callable = run_query ,
impl = run_query_impl ,
),
}Pyanalyze通常旨在实施Python键入规格,但对某些功能的支持是不完整的。有关详细信息,请参见文档。
有时,pyanalyze会弄错问题,您需要忽略它发出的错误。这可以如下完成:
# static analysis: ignore一行。# static analysis: ignore 。# static analysis: ignore文件顶部;这将忽略整个文件中的错误。您可以添加一个错误代码,例如# static analysis: ignore[undefined_name] ,仅忽略特定的错误代码。这不适合全文件忽略。如果bare_ignore错误代码已打开,则pyanalyze如果未在ighore评论中指定错误代码,则会发出错误。
Pyanalyze当前不支持标准# type: ignore评论语法。
Pyanalyze支持尚未达到寿命的所有版本的Python。因为它导入了它检查的代码,因此您必须使用与运行代码的相同版本的Python进行运行。
我们欢迎您的贡献。有关如何入门,请参见贡献。
文档可在ReadThedocs或Github上找到。