Comment puis-je vérifier la syntaxe du script Python sans l'exécuter?

368

J'avais l'habitude d'utiliser perl -c programfilepour vérifier la syntaxe d'un programme Perl puis quitter sans l'exécuter. Existe-t-il un moyen équivalent de le faire pour un script Python?

Eugene Yarmash
la source

Réponses:

590

Vous pouvez vérifier la syntaxe en la compilant:

python -m py_compile script.py
Mark Johnson
la source
9
import script, mais tout le code doit être dans les fonctions. Ce qui est de toute façon une bonne pratique. J'ai même adopté cela pour les scripts shell. De là, c'est une petite étape pour les tests unitaires.
Henk Langeveld
1
ne fonctionnera pas si vous avez un moteur embarqué avec des modules injectés
n611x007
57
python -m compileallpeut également faire des répertoires récursivement et a une meilleure interface en ligne de commande.
C2H5OH
9
Excellente réponse, mais comment puis-je l'empêcher de créer un fichier ".pyc"? A quoi sert le fichier ".pyc" au fait?
pdubois
4
Pour Python 2.7.9, quand -m py_compileest présent, je constate que ni -Bne PYTHONDONTWRITEBYTECODEsupprime la création du fichier .pyc .
DavidRR
59

Vous pouvez utiliser ces outils:

user225312
la source
11
Tous ces éléments font bien plus que vérifier la syntaxe. Ce n'est vraiment pas la réponse.
Matt Joiner
22
Tous ces éléments vérifient la syntaxe, donc la réponse est correcte. Les autres chèques sont un bonus (très utile).
johndodo
20
import sys
filename = sys.argv[1]
source = open(filename, 'r').read() + '\n'
compile(source, filename, 'exec')

Enregistrez-le sous checker.py et exécutez python checker.py yourpyfile.py.

Rosh Oxymoron
la source
1
Un peu trop lourd pour un Makefile pour une petite collection de scripts, mais il fait le travail et ne produit aucun fichier indésirable.
proski
1
C'est une vieille réponse, mais quelque chose à noter est que cela ne vérifie que la syntaxe, pas si le script s'exécute avec succès.
vallentin
Merci beaucoup. Ça marche. Un seul commentaire, il n'y a pas de réponse si le code est correct. Sinon, des messages d'erreur avec des numéros de ligne sont affichés.
musbach
5

Voici une autre solution, en utilisant le astmodule:

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

Pour le faire proprement à partir d'un 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)
jmd_dk
la source
1
Impressionnant one-liner qui ne nécessite pas toutes les bibliothèques importées ni ne produit de fichiers .pyc. Merci!
mmell
1

Pyflakes fait ce que vous demandez, il vérifie simplement la syntaxe. De la documentation:

Pyflakes fait une promesse simple: il ne se plaindra jamais de style, et il s'efforcera très, très fort de ne jamais émettre de faux positifs.

Pyflakes est également plus rapide que Pylint ou Pychecker. C'est en grande partie parce que Pyflakes examine uniquement l'arbre de syntaxe de chaque fichier individuellement.

Pour installer et utiliser:

$ pip install pyflakes
$ pyflakes yourPyFile.py
Brian C.
la source
0

pour une raison quelconque (je suis un débutant py ...) l'appel -m n'a pas fonctionné ...

voici donc une fonction bash wrapper ...

# ---------------------------------------------------------
# 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
la source