Как я могу проверить синтаксис скрипта Python, не выполняя его?


368

Раньше я использовал perl -c programfileдля проверки синтаксиса Perl-программы, а затем выйти без его выполнения. Есть ли эквивалентный способ сделать это для скрипта Python?

Ответы:


590

Вы можете проверить синтаксис, скомпилировав его:

python -m py_compile script.py

9
import script, но весь код должен быть в функциях. В любом случае, это хорошая практика. Я даже принял это для сценариев оболочки. Отсюда небольшой шаг к юнит-тестированию.
Хенк Лангевелд

1
не будет работать, если у вас встроенный движок с внедренными модулями
n611x007

57
python -m compileallможет также делать каталоги рекурсивно и имеет лучший интерфейс командной строки.
C2H5OH

9
Отличный ответ, но как я могу предотвратить это для создания файла ".pyc"? Какая польза от файла ".pyc"?
pdubois

4
Для Python 2.7.9, когда -m py_compileон присутствует, я обнаружил, что ни то, ни другое -Bне PYTHONDONTWRITEBYTECODEподавляет создание файла .pyc .
DavidRR

59

Вы можете использовать эти инструменты:


11
Все они делают гораздо больше, чем просто проверяют синтаксис. На самом деле это не ответ.
Мэтт Столяр

22
Все они проверяют синтаксис, поэтому ответ правильный. Другие чеки (очень полезный) бонус.
Johndodo

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

Сохраните это как checker.py и запустите python checker.py yourpyfile.py.


1
Слишком тяжелый для Makefile для крошечной коллекции скриптов, но он выполняет свою работу и не создает никаких нежелательных файлов.
Проски

1
Это старый ответ, но следует обратить внимание на то, что он проверяет только синтаксис, а не в случае успешного выполнения сценария.
Валлентин

Большое спасибо. Оно работает. Только один комментарий, нет ответа, если код правильный. В противном случае отображаются сообщения об ошибках с номерами строк.
musbach

5

Вот еще одно решение, использующее astмодуль:

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

Чтобы сделать это чисто из скрипта 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
Потрясающий однострочник, который не требует всех импортированных библиотек или создания файлов .pyc. Спасибо!
mmell


1

Pyflakes делает то, что вы просите, он просто проверяет синтаксис. Из документов:

Pyflakes дает простое обещание: он никогда не будет жаловаться на стиль, и он будет очень, очень сильно стараться никогда не испускать ложных срабатываний.

Pyflakes также быстрее, чем Pylint или Pychecker. Во многом это связано с тем, что Pyflakes проверяет только синтаксическое дерево каждого файла в отдельности.

Для установки и использования:

$ pip install pyflakes
$ pyflakes yourPyFile.py

0

по какой-то причине (я новичок пи ...) вызов -m не работает ...

так вот функция оболочки 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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.