def ptl_compile(file, cfile, dfile=None, doraise=False, optimize=-1): """Byte-compile one PTL source file to Python bytecode. :param file: The source file name. :param cfile: The target byte compiled 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 PyCompileError 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. :return: Path to the resulting byte compiled file. Do note that FileExistsError is raised if cfile ends up pointing at a non-regular file or symlink. Because the compilation uses a file renaming, the resulting file would be regular and thus not the same type of file as it was previously. """ # derived from py_compile.compile if os.path.islink(cfile): msg = ('{} is a symlink and will be changed into a regular file if ' 'import writes a byte-compiled file to it') raise FileExistsError(msg.format(cfile)) elif os.path.exists(cfile) and not os.path.isfile(cfile): msg = ('{} is a non-regular file and will be changed into a regular ' 'one if import writes a byte-compiled file to it') raise FileExistsError(msg.format(cfile)) loader = PTLFileLoader('<ptl_compile>', file) source_bytes = loader.get_data(file) try: code = loader.source_to_code(source_bytes, dfile or file, _optimize=optimize) except Exception as err: py_exc = py_compile.PyCompileError(err.__class__, err, dfile or file) if doraise: raise py_exc else: sys.stderr.write(py_exc.msg + '\n') return try: dirname = os.path.dirname(cfile) if dirname: os.makedirs(dirname) except FileExistsError: pass source_stats = loader.path_stats(file) bytecode = _code_to_bytecode(code, source_stats['mtime'], source_stats['size']) mode = importlib._bootstrap_external._calc_mode(file) importlib._bootstrap_external._write_atomic(cfile, bytecode, mode) return cfile
def compile_template(input, filename, output=None): """(input, filename) -> code Compile an open file. The code object is returned. """ source_bytes = input.read() loader = PTLFileLoader('<ptl_compile>', filename) code = loader.source_to_code(source_bytes, filename) if output is not None: # The 'output' parameter is for backwards compatibility with old # versions of Quixote. New code should not supply it. bytecode = _code_to_bytecode(code, 0, 0) output.write(bytecode) return code