Come posso verificare la sintassi dello script Python senza eseguirla?


368

Prima usavo perl -c programfileper controllare la sintassi di un programma Perl e poi uscire senza eseguirlo. Esiste un modo equivalente per farlo per uno script Python?

Risposte:


590

Puoi verificare la sintassi compilandola:

python -m py_compile script.py

9
import script, ma tutto il codice deve essere nelle funzioni. Che è comunque una buona pratica. L'ho persino adottato per gli script di shell. Da qui è un piccolo passo verso i test unitari.
Henk Langeveld,

1
non funzionerà se si dispone di un motore incorporato con moduli iniettati
n611x007,

57
python -m compileallpuò anche fare ricorsivamente directory e ha una migliore interfaccia a riga di comando.
C2H5OH,

9
Ottima risposta, ma come posso impedirlo per la creazione del file ".pyc"? A proposito, a che cosa serve il file ".pyc"?
pdubois

4
Per Python 2.7.9, quando -m py_compileè presente, sto scoprendo che -BPYTHONDONTWRITEBYTECODEsopprime né crea il file .pyc .
DavidRR

59

Puoi usare questi strumenti:


10
Tutti questi fanno molto di più che controllare la sintassi. Davvero questa non è la risposta.
Matt Joiner,

22
Tutti questi controllano la sintassi, quindi la risposta è corretta. Altri controlli sono un bonus (molto utile).
johndodo,

20
import sys
filename = sys.argv[1]
source = open(filename, 'r').read() + '\n'
compile(source, filename, 'exec')

Salvalo come checker.py ed eseguilo python checker.py yourpyfile.py.


1
Un po 'troppo pesante per un Makefile per una piccola raccolta di script, ma fa il lavoro e non produce alcun file indesiderato.
proski,

1
È una vecchia risposta, ma qualcosa da notare è che questo controlla solo la sintassi, non se lo script verrà eseguito correttamente.
Vallentin,

Molte grazie. Funziona. Solo un commento, non c'è risposta se il codice è corretto. Altrimenti vengono visualizzati messaggi di errore con numeri di riga.
musbach,

5

Ecco un'altra soluzione, utilizzando il astmodulo:

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

Per farlo in modo pulito dall'interno di uno script 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)

1
Impressionante one-liner che non richiede tutte le librerie importate o produce file .pyc. Grazie!
mmell


1

Pyflakes fa quello che chiedi, controlla solo la sintassi. Dai documenti:

Pyflakes fa una semplice promessa: non si lamenterà mai dello stile e cercherà molto, molto duramente, di non emettere falsi positivi.

Pyflakes è anche più veloce di Pylint o Pychecker. Ciò è in gran parte dovuto al fatto che Pyflakes esamina solo l'albero della sintassi di ciascun file singolarmente.

Per installare e utilizzare:

$ pip install pyflakes
$ pyflakes yourPyFile.py

0

per qualche motivo (sono un principiante py ...) la chiamata -m non ha funzionato ...

quindi ecco una funzione wrapper 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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.