Oct-19-2024, 08:19 AM
The following code is a CLI script to check the syntax of python code. Here is the usage string
Output:usage: check_syntax.py [-h] FILENAME [FILENAME ...]
Check Python source file syntax by attempting compilation.
positional arguments:
FILENAME Files to compile
options:
-h, --help show this help message and exit
Further updates of this code will happen in this gist.# check_syntax.py - script to check the syntax of Python files # inspired by the standard library's 'py_compile' module. import importlib.machinery import sys import traceback __all__ = ["has_valid_syntax", "main", "CheckSyntaxError"] class CheckSyntaxError(Exception): """Exception raised when an error occurs while attempting to compile the file. To raise this exception, use raise PyCompileError(exc_type,exc_value,file[,msg]) where exc_type: exception type to be used in error message type name can be accesses as class variable 'exc_type_name' exc_value: exception value to be used in error message can be accesses as class variable 'exc_value' file: name of file being compiled to be used in error message can be accesses as class variable 'file' msg: string message to be written as error message If no value is given, a default exception message will be given, consistent with 'standard' py_compile output. message (or default) can be accesses as class variable 'msg' """ def __init__(self, exc_type, exc_value, file, msg=""): exc_type_name = exc_type.__name__ if exc_type is SyntaxError: tbtext = "".join(traceback.format_exception_only(exc_type, exc_value)) errmsg = tbtext.replace('File "<string>"', 'File "%s"' % file) else: errmsg = "Sorry: %s: %s" % (exc_type_name, exc_value) Exception.__init__(self, msg or errmsg, exc_type_name, exc_value, file) self.exc_type_name = exc_type_name self.exc_value = exc_value self.file = file self.msg = msg or errmsg def __str__(self): return self.msg def has_valid_syntax(file, dfile=None, doraise=False, optimize=-1, quiet=0): """Check the syntax of a Python source file. :param file: The source file name. :param dfile: Purported file name, i.e. the file name that shows up in error messages. Defaults to the source file name. :param doraise: Flag indicating whether or not an exception should be raised when a compile error is found. If an exception occurs and this flag is set to False, a string indicating the nature of the exception will be printed, and the function will return to the caller. If an exception occurs and this flag is set to True, a CheckSyntaxError exception will be raised. :param optimize: The optimization level for the compiler. Valid values are -1, 0, 1 and 2. A value of -1 means to use the optimization level of the current interpreter, as given by -O command line options. :param quiet: Return full output with False or 0, errors only with 1, and no output with 2. :return: None """ loader = importlib.machinery.SourceFileLoader("<py_compile>", file) source_bytes = loader.get_data(file) try: compile(source_bytes, dfile or file, "exec", optimize=optimize) except Exception as err: py_exc = CheckSyntaxError(err.__class__, err, dfile or file) if quiet < 2: if doraise: raise py_exc else: sys.stderr.write(py_exc.msg + "\n") return False else: return True def main(): import argparse description = "Check Python source file syntax by attempting compilation." parser = argparse.ArgumentParser(description=description) parser.add_argument( "filenames", nargs="+", help="Files to compile", metavar="FILENAME", ) args = parser.parse_args() if args.filenames == ["-"]: filenames = [filename.rstrip("\n") for filename in sys.stdin.readlines()] else: filenames = args.filenames result = True kwargs = {"doraise": False, "quiet": 0} for filename in filenames: filename = filename.rstrip("\n") result = has_valid_syntax(filename, **kwargs) and result else: return parser.exit(0 if result else 1) if __name__ == "__main__": main()
« We can solve any problem by introducing an extra level of indirection »