Bagaimana saya bisa memeriksa sintaks skrip Python tanpa menjalankannya?

368

Saya biasa menggunakan perl -c programfileuntuk memeriksa sintaks program Perl dan kemudian keluar tanpa menjalankannya. Apakah ada cara yang setara untuk melakukan ini untuk skrip Python?

Eugene Yarmash
sumber

Jawaban:

590

Anda dapat memeriksa sintaks dengan mengompilasinya:

python -m py_compile script.py
Mark Johnson
sumber
9
import script, tetapi semua kode harus dalam fungsi. Yang merupakan praktik yang baik pula. Saya bahkan sudah mengadopsi ini untuk skrip shell. Dari sini, ini adalah langkah kecil menuju unit testing.
Henk Langeveld
1
tidak akan berfungsi jika Anda memiliki mesin tertanam dengan modul yang disuntikkan
n611x007
57
python -m compilealljuga dapat melakukan direktori secara rekursif dan memiliki antarmuka baris perintah yang lebih baik.
C2H5OH
9
Jawaban yang bagus, tetapi bagaimana saya bisa mencegahnya untuk membuat file ".pyc"? Apa gunanya file ".pyc"?
pdubois
4
Untuk Python 2.7.9, ketika -m py_compileada, saya menemukan bahwa tidak ada -Batau tidak PYTHONDONTWRITEBYTECODEmenekan pembuatan file .pyc .
DavidRR
59

Anda dapat menggunakan alat ini:

pengguna225312
sumber
10
Semua ini lebih dari sekadar memeriksa sintaksis. Sungguh ini bukan jawabannya.
Matt Joiner
22
Semua ini memeriksa sintaks, jadi jawabannya sudah benar. Cek lainnya adalah bonus (sangat berguna).
johndodo
20
import sys
filename = sys.argv[1]
source = open(filename, 'r').read() + '\n'
compile(source, filename, 'exec')

Simpan ini sebagai checker.py dan jalankan python checker.py yourpyfile.py.

Rosh Oxymoron
sumber
1
Agak terlalu berat untuk Makefile untuk koleksi skrip kecil, tetapi berfungsi dan tidak menghasilkan file yang tidak diinginkan.
proski
1
Ini adalah jawaban lama, tetapi sesuatu yang perlu diperhatikan adalah ini hanya memeriksa sintaks, bukan jika skrip akan berhasil dijalankan.
vallentin
Terima kasih banyak. Berhasil. Hanya satu komentar, tidak ada jawaban jika kodenya benar. Kalau tidak, pesan kesalahan dengan nomor baris ditampilkan.
Musbach
5

Inilah solusi lain, menggunakan astmodul:

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

Untuk melakukannya dengan bersih dari dalam skrip 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
sumber
1
Mengagumkan one-liner yang tidak memerlukan semua lib yang diimpor atau menghasilkan file .pyc. Terima kasih!
mmell
1

Pyflakes melakukan apa yang Anda minta, itu hanya memeriksa sintaks. Dari dokumen:

Pyflakes membuat janji sederhana: ia tidak akan pernah mengeluh tentang gaya, dan itu akan berusaha sangat, sangat sulit untuk tidak pernah memancarkan positif palsu.

Pyflakes juga lebih cepat dari Pylint atau Pychecker. Ini sebagian besar karena Pyflakes hanya memeriksa pohon sintaks dari setiap file secara individual.

Untuk menginstal dan menggunakan:

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

untuk beberapa alasan (saya seorang pemula py ...) panggilan -m tidak berfungsi ...

jadi di sini adalah fungsi ...

# ---------------------------------------------------------
# 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
sumber