Hoe kan ik de syntaxis van het Python-script controleren zonder het uit te voeren?

Vroeger gebruikte ik perl -c programfileom de syntaxis van een Perl-programma te controleren en vervolgens af te sluiten zonder het uit te voeren. Is er een gelijkwaardige manier om dit te doen voor een Python-script?


Antwoord 1, autoriteit 100%

U kunt de syntaxis controleren door deze te compileren:

python -m py_compile script.py

Antwoord 2, autoriteit 10%

U kunt deze tools gebruiken:


Antwoord 3, autoriteit 3%

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

Sla dit op als checker.py en voer python checker.py yourpyfile.pyuit.


Antwoord 4, autoriteit 2%

Hier is een andere oplossing, met behulp van de astmodule:

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

Om het netjes te doen vanuit een Python-script:

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)

Antwoord 5

Pyflakes doet wat je vraagt, het controleert alleen de syntaxis. Uit de documenten:

Pyflakes doet een simpele belofte: het zal nooit klagen over stijl, en het zal heel, heel erg zijn best doen om nooit valse positieven uit te zenden.

Pyflakes is ook sneller dan Pylint of Pychecker. Dit komt grotendeels omdat Pyflakes alleen de syntaxisstructuur van elk bestand afzonderlijk onderzoekt.

Installeren en gebruiken:

$ pip install pyflakes
$ pyflakes yourPyFile.py

Antwoord 6

python -m compileall -q .

Zal alles recursief in de huidige map compileren en alleen fouten afdrukken.

$ python -m compileall --help
usage: compileall.py [-h] [-l] [-r RECURSION] [-f] [-q] [-b] [-d DESTDIR] [-x REGEXP] [-i FILE] [-j WORKERS] [--invalidation-mode {checked-hash,timestamp,unchecked-hash}] [FILE|DIR [FILE|DIR ...]]
Utilities to support installing Python libraries.
positional arguments:
  FILE|DIR              zero or more file and directory names to compile; if no arguments given, defaults to the equivalent of -l sys.path
optional arguments:
  -h, --help            show this help message and exit
  -l                    don't recurse into subdirectories
  -r RECURSION          control the maximum recursion level. if `-l` and `-r` options are specified, then `-r` takes precedence.
  -f                    force rebuild even if timestamps are up to date
  -q                    output only error messages; -qq will suppress the error messages as well.
  -b                    use legacy (pre-PEP3147) compiled file locations
  -d DESTDIR            directory to prepend to file paths for use in compile-time tracebacks and in runtime tracebacks in cases where the source file is unavailable
  -x REGEXP             skip files matching the regular expression; the regexp is searched for in the full path of each file considered for compilation
  -i FILE               add all the files and directories listed in FILE to the list considered for compilation; if "-", names are read from stdin
  -j WORKERS, --workers WORKERS
                        Run compileall concurrently
  --invalidation-mode {checked-hash,timestamp,unchecked-hash}
                        set .pyc invalidation mode; defaults to "checked-hash" if the SOURCE_DATE_EPOCH environment variable is set, and "timestamp" otherwise.

De afsluitwaarde is 1 wanneer syntaxisfouten zijn gevonden.

Bedankt C2H5OH.


Antwoord 7

Misschien handige online checker PEP8: http://pep8online.com/


Antwoord 8

om de een of andere reden (ik ben een py-newbie … ) werkte de -m-oproep niet …

dus hier is een bash-wrapper-functie …

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

Antwoord 9

Dankzij de bovenstaande antwoorden @Rosh Oxymoron. Ik heb het script verbeterd om alle bestanden in een map te scannen die python-bestanden zijn. Dus voor ons luie mensen, geef het gewoon de map en het zal alle bestanden in die map scannen die python zijn.

import sys
import glob, os
os.chdir(sys.argv[1])
for file in glob.glob("*.py"):
    source = open(file, 'r').read() + '\n'
    compile(source, file, 'exec')

Save this as checker.py and run python checker.py ~/YOURDirectoryTOCHECK

Other episodes