Esempio n. 1
0
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
Esempio n. 2
0
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