Online Shopping : Computers : Programming : Languages : Python : Snippets

+ Search
Add Entry AlertManage Folder Edit Entry Add page to
Did You Find This Entry Useful?

5 of 5 people (100%) answered Yes
Recently 3 of 3 people (100%) answered Yes


Syntax checker

Jul 5th, 2000 10:03
Nathan Wallace, Hans Nowak, Snippet 333, Preston Landers

Packages: miscellaneous
From:           	Preston Landers <[email protected]>
Subject:        	syntax checking underway; question about catching exceptions
Date sent:      	Wed, 01 Dec 1999 23:55:34 GMT
Organization: - Before you buy.
To:             	[email protected]
A big thanks to those who answered my question yesterday about doing a
syntax check with compile().
I've got some code going that I've found useful, and I thought I would
share it (below.)
The reason that I'm posting is that I'm having a bit of trouble
catching the syntax exceptions appropriately.  What I want to find out
is the line number / statement that caused compile to fail.
If I simply do this:
compile(file, "", "exec")
then, upon a syntax error, the resulting traceback contains all the
information I need to go in and fix the problem.  However, the program
is aborted at that point, and I can't do any post-processing or check
any of the remaining python files.
If I catch the exception like so:
  compile(file, "", "exec")
  exception, msg, tb = sys.exc_info()
  # look at traceback here
then I effectively lose where in the source file the exception
occured.  If I examine the tb with the traceback module, I get
something like this:
  File "./", line 36, in examine_files
    compile(file, "", "exec")
So I can do post-processing, check other files, and so on, which is
nice, but I am not able to determine automatically where the problem is
in the source file.  So, it's effectively useless.
I can't figure out how to get what I want!  You would think that all
the information I need would be in the tb object, because if I don't
wrap compile() in a try: except: all that information *is* in the
traceback.  What's going on?
Below is the program I'm using to do a simple python syntax check.  I
put a call to this at the end of my Makefile.  It does currently rely
on the Unix 'find' command, so if you're using a lesser OS, you will
have to adapt. ;-)
#!/usr/bin/env python1.5
"""This program does a syntax check on Python files.
use -r or --recursive to delve into subdirectories
(default is to only examine current dir)
use -c or --continue to keep going after an error has been found.
Copyright 1999 Preston Landers <[email protected]>"""
import os, sys, string, traceback, commands, getopt
def get_files_to_examine(recursive = None):
    """returns a list of paths to Python files to be checked.  If
       recursive is set, then will delve into subdirs."""
    if recursive:
        find_cmd = 'find . -name \*.py'
        find_cmd = 'find . -maxdepth 1 -name \*.py'
    status, output = commands.getstatusoutput(find_cmd)
    if status:
        print output
        print "Find failed...?"
        raise SystemExit(1)
    files = string.split(output, "\n")
    return files
def examine_files(python_files, err_continue = None):
    ### do the test
    for python_file in python_files:
        file = open(python_file).read()
        ### this whole try: except: block is neccesary if
        ### you want to be able to continue after errors
            compile(file, python_file, "exec")
            exception, msg, tb = sys.exc_info()
            print "%s:  %s: %s" % (python_file, exception, msg)
            if not err_continue:
                print "ABORTING"
                raise SystemExit(1)
            print "%s: GOOD" % python_file
        ### this is what I would use if I wanted to see exactly
        ### where the error occured (each error will halt program)
        # compile(file, python_file, "exec")
if __name__ == "__main__":
    recursive = None  # assume not recursive
    err_continue = None  # assume break on error
        options, args = getopt.getopt(sys.argv[1:], 'hrc',
        ["help", "recursive", "continue"])
        print "Unrecognized option."
        print __doc__
        raise SystemExit(1)
    for option_name, option_value in options:
        if option_name in ["-h", "--help"]:
            print __doc__
            raise SystemExit(0)
        elif option_name in ["-r", "--recursive"]:
            recursive = 1
        elif option_name in ["-c", "--continue"]:
            err_continue = 1
    files_to_examine = get_files_to_examine(recursive)
    examine_files(files_to_examine, err_continue)
    raise SystemExit(0) # success