diff options
author | Martin v. Löwis <martin@v.loewis.de> | 2003-01-15 11:51:06 (GMT) |
---|---|---|
committer | Martin v. Löwis <martin@v.loewis.de> | 2003-01-15 11:51:06 (GMT) |
commit | 0c6774d92b48c4c4097a3a3bea2294093092e4e3 (patch) | |
tree | 99fca658cecaee2a9ec1d8bff51357bc8e61c504 /Lib/py_compile.py | |
parent | d69663d3009b6718ed3fa27dec800d15c7d4babb (diff) | |
download | cpython-0c6774d92b48c4c4097a3a3bea2294093092e4e3.zip cpython-0c6774d92b48c4c4097a3a3bea2294093092e4e3.tar.gz cpython-0c6774d92b48c4c4097a3a3bea2294093092e4e3.tar.bz2 |
Patch #661719: Expose compilation errors as exceptions on request.
Diffstat (limited to 'Lib/py_compile.py')
-rw-r--r-- | Lib/py_compile.py | 92 |
1 files changed, 75 insertions, 17 deletions
diff --git a/Lib/py_compile.py b/Lib/py_compile.py index 2d5c36a..95d6a08 100644 --- a/Lib/py_compile.py +++ b/Lib/py_compile.py @@ -12,7 +12,54 @@ import traceback MAGIC = imp.get_magic() -__all__ = ["compile", "main"] +__all__ = ["compile", "main", "PyCompileError"] + + +class PyCompileError(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 + # Define an internal helper according to the platform if os.name == "mac": @@ -30,17 +77,24 @@ def wr_long(f, x): f.write(chr((x >> 16) & 0xff)) f.write(chr((x >> 24) & 0xff)) -def compile(file, cfile=None, dfile=None): +def compile(file, cfile=None, dfile=None, doraise=False): """Byte-compile one Python source file to Python bytecode. Arguments: - file: source filename - cfile: target filename; defaults to source with 'c' or 'o' appended - ('c' normally, 'o' in optimizing mode, giving .pyc or .pyo) - dfile: purported filename; defaults to source (this is the filename - that will show up in error messages) - + file: source filename + cfile: target filename; defaults to source with 'c' or 'o' appended + ('c' normally, 'o' in optimizing mode, giving .pyc or .pyo) + dfile: purported filename; defaults to source (this is the filename + that will show up in error messages) + 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 + PyCompileError exception will be raised. + Note that it isn't necessary to byte-compile Python modules for execution efficiency -- Python itself byte-compiles a module when it is loaded, and if it can, writes out the bytecode to the @@ -68,13 +122,14 @@ def compile(file, cfile=None, dfile=None): if codestring and codestring[-1] != '\n': codestring = codestring + '\n' try: - codeobject = __builtin__.compile(codestring, dfile or file, 'exec') - except SyntaxError, detail: - lines = traceback.format_exception_only(SyntaxError, detail) - for line in lines: - sys.stderr.write(line.replace('File "<string>"', - 'File "%s"' % (dfile or file))) - return + codeobject = __builtin__.compile(codestring, dfile or file,'exec') + except Exception,err: + py_exc = PyCompileError(err.__class__,err.args,dfile or file) + if doraise: + raise py_exc + else: + sys.stderr.write(py_exc.msg) + return if cfile is None: cfile = file + (__debug__ and 'c' or 'o') fc = open(cfile, 'wb') @@ -100,7 +155,10 @@ def main(args=None): if args is None: args = sys.argv[1:] for filename in args: - compile(filename) - + try: + compile(filename, doraise=True) + except PyCompileError,err: + sys.stderr.write(err.msg) + if __name__ == "__main__": main() |