Jak mogę sprawdzić składnię skryptu Python bez wykonywania go?

368

Kiedyś perl -c programfilesprawdzałem składnię programu Perl, a następnie kończyłem działanie bez jego wykonywania. Czy istnieje równoważny sposób na wykonanie tego w przypadku skryptu Python?

Eugene Yarmash
źródło

Odpowiedzi:

590

Możesz sprawdzić składnię, kompilując ją:

python -m py_compile script.py
Mark Johnson
źródło
9
import script, ale cały kod musi znajdować się w funkcjach. Co i tak jest dobrą praktyką. Zaadaptowałem to nawet do skryptów powłoki. Od tego momentu jest to mały krok do testów jednostkowych.
Henk Langeveld,
1
nie będzie działać, jeśli masz wbudowany silnik z wstrzykiwanymi modułami
n611x007
57
python -m compileallpotrafi także rekursywnie tworzyć katalogi i ma lepszy interfejs wiersza poleceń.
C2H5OH,
9
Świetna odpowiedź, ale jak mogę temu zapobiec przy tworzeniu pliku „.pyc”? Przy okazji, jaki jest pożytek z pliku „.pyc”?
pdubois
4
W przypadku Python 2.7.9, gdy -m py_compilejest obecny, stwierdzam, że ani -Bnie PYTHONDONTWRITEBYTECODEhamuje tworzenia pliku .pyc .
DavidRR,
59

Możesz użyć tych narzędzi:

użytkownik225312
źródło
10
Wszystkie z nich robią znacznie więcej niż sprawdzanie składni. Naprawdę to nie jest odpowiedź.
Matt Joiner
22
Wszystkie te sprawdzają składnię, więc odpowiedź jest poprawna. Inne czeki to (bardzo przydatny) bonus.
johndodo
19
import sys
filename = sys.argv[1]
source = open(filename, 'r').read() + '\n'
compile(source, filename, 'exec')

Zapisz to jako checker.py i uruchom python checker.py yourpyfile.py.

Rosz Oxymoron
źródło
1
Trochę za ciężki jak na Makefile dla niewielkiej kolekcji skryptów, ale wykonuje to zadanie i nie generuje niechcianych plików.
proski
1
To stara odpowiedź, ale należy zauważyć, że sprawdza to tylko składnię, a nie wykonanie skryptu.
vallentin
Wielkie dzięki. To działa. Tylko jeden komentarz, nie ma odpowiedzi, jeśli kod jest poprawny. W przeciwnym razie wyświetlane są komunikaty o błędach z numerami linii.
musbach
5

Oto inne rozwiązanie wykorzystujące astmoduł:

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

Aby zrobić to czysto z poziomu skryptu 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
źródło
1
Niesamowity jednowierszowy, który nie wymaga wszystkich importowanych bibliotek ani tworzenia plików .pyc. Dzięki!
mmell
1

Pyflakes robi to, o co prosisz, po prostu sprawdza składnię. Z dokumentów:

Pyflakes składa prostą obietnicę: nigdy nie narzeka na styl i bardzo, bardzo stara się nigdy nie emitować fałszywych alarmów.

Pyflakes jest również szybszy niż Pylint lub Pychecker. Wynika to głównie z tego, że Pyflakes sprawdza tylko drzewo składni każdego pliku osobno.

Aby zainstalować i używać:

$ pip install pyflakes
$ pyflakes yourPyFile.py
Brian C.
źródło
0

z jakiegoś powodu (jestem py nowicjuszem ...) połączenie -m nie działało ...

więc tutaj jest bash wrapper func ...

# ---------------------------------------------------------
# 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
źródło