¿Cómo puedo verificar la sintaxis del script Python sin ejecutarlo?

368

Solía ​​usar perl -c programfilepara verificar la sintaxis de un programa Perl y luego salir sin ejecutarlo. ¿Hay una forma equivalente de hacer esto para un script de Python?

Eugene Yarmash
fuente

Respuestas:

590

Puede verificar la sintaxis compilándola:

python -m py_compile script.py
Mark Johnson
fuente
99
import script, pero todo el código debe estar en funciones. Lo cual es una buena práctica de todos modos. Incluso he adoptado esto para los scripts de shell. A partir de aquí, es un pequeño paso para las pruebas unitarias.
Henk Langeveld
1
no funcionará si tiene un motor integrado con módulos inyectados
n611x007
57
python -m compileallTambién puede hacer directorios de forma recursiva y tiene una mejor interfaz de línea de comandos.
C2H5OH
99
Gran respuesta, pero ¿cómo puedo evitar que cree un archivo ".pyc"? ¿Cuál es el uso del archivo ".pyc" por cierto?
pdubois
44
Para Python 2.7.9, cuando -m py_compileestá presente, encuentro que -Bni PYTHONDONTWRITEBYTECODEsuprime la creación del archivo .pyc .
DavidRR
59

Puedes usar estas herramientas:

usuario225312
fuente
10
Todos estos hacen mucho más que verificar la sintaxis. Realmente esta no es la respuesta.
Matt Joiner
22
Todo esto verifica la sintaxis, por lo que la respuesta es correcta. Otros cheques son una bonificación (muy útil).
johndodo
20
import sys
filename = sys.argv[1]
source = open(filename, 'r').read() + '\n'
compile(source, filename, 'exec')

Guarde esto como checker.py y ejecútelo python checker.py yourpyfile.py.

Rosh Oxymoron
fuente
1
Un poco demasiado pesado para un Makefile para una pequeña colección de scripts, pero hace el trabajo y no produce ningún archivo no deseado.
Proski
1
Es una respuesta antigua, pero algo a tener en cuenta es que esto solo verifica la sintaxis, no si el script se ejecutará con éxito.
vallentin
Muchas gracias. Funciona. Solo un comentario, no hay respuesta si el código es correcto. De lo contrario, se muestran mensajes de error con números de línea.
musbach
5

Aquí hay otra solución, usando el astmódulo:

python -c "import ast; ast.parse(open('programfile').read())"

Para hacerlo limpiamente desde un script de Python:

import ast, traceback

filename = 'programfile'
with open(filename) as f:
    source = f.read()
valid = True
try:
    ast.parse(source)
except SyntaxError:
    valid = False
    traceback.print_exc()  # Remove to silence any errros
print(valid)
jmd_dk
fuente
1
Impresionante one-liner que no requiere todas las librerías importadas ni produce archivos .pyc. ¡Gracias!
mmell
1

Pyflakes hace lo que le pides, solo verifica la sintaxis. De los documentos:

Pyflakes hace una promesa simple: nunca se quejará del estilo, e intentará muy, muy difícil nunca emitir falsos positivos.

Pyflakes también es más rápido que Pylint o Pychecker. Esto se debe principalmente a que Pyflakes solo examina el árbol de sintaxis de cada archivo individualmente.

Para instalar y usar:

$ pip install pyflakes
$ pyflakes yourPyFile.py
Brian C.
fuente
0

por alguna razón (soy un novato py ...) la llamada -m no funcionó ...

así que aquí hay una función de envoltura bash ...

# ---------------------------------------------------------
# check the python synax for all the *.py files under the
# <<product_version_dir/sfw/python
# ---------------------------------------------------------
doCheckPythonSyntax(){

    doLog "DEBUG START doCheckPythonSyntax"

    test -z "$sleep_interval" || sleep "$sleep_interval"
    cd $product_version_dir/sfw/python
    # python3 -m compileall "$product_version_dir/sfw/python"

    # foreach *.py file ...
    while read -r f ; do \

        py_name_ext=$(basename $f)
        py_name=${py_name_ext%.*}

        doLog "python3 -c \"import $py_name\""
        # doLog "python3 -m py_compile $f"

        python3 -c "import $py_name"
        # python3 -m py_compile "$f"
        test $! -ne 0 && sleep 5

    done < <(find "$product_version_dir/sfw/python" -type f -name "*.py")

    doLog "DEBUG STOP  doCheckPythonSyntax"
}
# eof func doCheckPythonSyntax
Yordan Georgiev
fuente