Pyanalyze-это полустатическая проверка типа для кода Python. Подобно статическому контролеру типа (например, Mypy или Pyright), он обнаруживает ошибки типа в вашем коде, поэтому ошибки можно найти, прежде чем они достигнут производства. Однако, в отличие от таких инструментов, он импортирует модули, которые проверяют тип, позволяя Pyanalyze понять многие динамические конструкции, которые будут отвергнуты другие шашки типа. Это свойство также позволяет расширить Pyanalyze с помощью плагинов, которые напрямую взаимодействуют с вашим кодом.
Вы можете установить Pyanalyze с:
$ pip install pyanalyzeПосле установки вы можете запустить Pyanalyze на файле или пакете Python следующим образом:
$ python -m pyanalyze file.py
$ python -m pyanalyze package/ Но обратите внимание, что это попытается импортировать все файлы Python, которые он проходит. Если у вас есть сценарии, которые выполняют операции без if __name__ == "__main__": блоки, Pyanalyze может в конечном итоге выполнить их.
Чтобы успешно работать, Pyanalyze должен иметь возможность импортировать код, который он проверяет. Чтобы сделать эту работу, вам, возможно, придется вручную отрегулировать путь импорта Python, используя переменную среды $PYTHONPATH .
Для быстрых экспериментов вы также можете использовать опцию -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 издает ошибку, если вы не указате код ошибки в комментарии игнорировать.
Pyanalyze в настоящее время не поддерживает стандартный # type: ignore синтаксис комментариев.
Pyanalyze поддерживает все версии Python, которые не достигли конца жизни. Поскольку он импортирует код, который он проверяет, вы должны запустить его, используя ту же версию Python, которую вы используете для запуска вашего кода.
Мы приветствуем ваш вклад. Смотрите applining.md о том, как начать.
Документация доступна в Readthedocs или на GitHub.