Pyanalyze es un verificador de tipo semiestático para el código Python. Al igual que un verificador de tipo estático (por ejemplo, mypy o pyright), detecta errores de tipo en su código para que se puedan encontrar errores antes de alcanzar la producción. Sin embargo, a diferencia de tales herramientas, importa los módulos que escribe verificaciones, lo que permite a Pyanalyze comprender muchas construcciones dinámicas que otros comprobantes de tipo rechazarán. Esta propiedad también permite extender Pyanalyze con complementos que interactúan directamente con su código.
Puede instalar Pyanalyze con:
$ pip install pyanalyzeUna vez que se instale, puede ejecutar Pyanalyze en un archivo o paquete de Python de la siguiente manera:
$ python -m pyanalyze file.py
$ python -m pyanalyze package/ Pero tenga en cuenta que esto intentará importar todos los archivos de Python que se pasa. Si tiene scripts que realizan operaciones sin if __name__ == "__main__": bloques, Pyanalyze puede terminar ejecutándolos.
Para ejecutarse con éxito, Pyanalyze necesita poder importar el código que verifica. Para hacer que este trabajo, es posible que deba ajustar manualmente la ruta de importación de Python utilizando la variable de entorno $PYTHONPATH .
Para una experimentación rápida, también puede usar la opción -c para escribir directamente un pedazo de código:
$ 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 tiene una serie de opciones de línea de comandos, que puede ver ejecutando python -m pyanalyze --help . Los importantes incluyen -f , que ejecuta un indicador interactivo que le permite examinar y corregir cada error encontrado por Pyanalyze, y, --enable / --disable , que habilite y deshabilite códigos de error específicos.
También es compatible con la configuración a través de un archivo pyproject.toml . Vea la documentación para más detalles.
Una de las formas principales de extender Pyanalyze es proporcionar una especificación para una función particular. Esto le permite ejecutar un código arbitrario que inspeccione los argumentos a la función y plantee errores si algo está mal.
Como ejemplo, suponga que su base de código contiene una función database.run_query() que toma como argumento una cadena SQL, como esta:
database . run_query ( "SELECT answer, question FROM content" ) Desea detectar cuando una llamada a run_query() contiene SQL sintácticamente inválido o se refiere a una tabla o columna inexistente. Podrías configurar eso con un código como este:
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 generalmente tiene como objetivo implementar la especificación de tipificación de Python, pero el soporte para algunas características está incompleto. Vea la documentación para más detalles.
A veces Pyanalyze se equivoca y debes ignorar un error que emite. Esto se puede hacer de la siguiente manera:
# static analysis: ignore en una línea por sí misma antes de la línea que genera el error.# static analysis: ignore al final de la línea que genera el error.# static analysis: ignore en la parte superior del archivo; Esto ignorará los errores en todo el archivo. Puede agregar un código de error, como # static analysis: ignore[undefined_name] , para ignorar solo un código de error específico. Esto no funciona para que se ignore por completo. Si se enciende el código de error bare_ignore , Pyanalyze emitirá un error si no especifica un código de error en un comentario ignorado.
Pyanalyze actualmente no admite el tipo estándar # type: ignore la sintaxis de comentarios.
Pyanalyze apoya todas las versiones de Python que no han alcanzado el final de la vida. Debido a que importa el código que verifica, debe ejecutarlo utilizando la misma versión de Python que usa para ejecutar su código.
Agradecemos sus contribuciones. Ver contribuyente.md sobre cómo comenzar.
La documentación está disponible en Readthedocs o en GitHub.