コード例 #1
0
ファイル: config.py プロジェクト: sarathkumarsivan/pytype
  def _store_python_exe(self, python_exe):
    """Postprocess --python_exe."""
    if python_exe is None and utils.can_compile_bytecode_natively(
        self.output_options.python_version):
      # The user has not requested a custom exe and pytype does not need an exe
      # for bytecode compilation. Abort early to avoid extracting a large unused
      # exe into /tmp.
      self.output_options.python_exe = (None, None)
      return

    if python_exe is None:
      python_exe, flags = utils.get_python_exe(
          self.output_options.python_version)
      user_provided_exe = False
    else:
      if isinstance(python_exe, tuple):
        python_exe, flags = python_exe
      else:
        flags = []
      user_provided_exe = True
    python_exe_version = utils.get_python_exe_version(python_exe)
    if python_exe_version != self.output_options.python_version:
      if not user_provided_exe:
        err = ("Need a valid python%d.%d executable in $PATH" %
               self.output_options.python_version)
      elif python_exe_version:
        err = ("--python_exe version %d.%d does not match "
               "--python_version %d.%d" % (
                   python_exe_version + self.output_options.python_version))
      else:
        err = "Bad flag --python_exe: could not run %s" % python_exe
      self.error(err)
    self.output_options.python_exe = (python_exe, flags)
コード例 #2
0
    def _store_python_version(self, python_version):
        """Configure the python version."""
        if python_version:
            if isinstance(python_version, str):
                version = utils.version_from_string(python_version)
            else:
                version = python_version
        else:
            version = sys.version_info[:2]
        if len(version) != 2:
            self.error("--python_version must be <major>.<minor>: %r" %
                       python_version)
        # Check that we have a version supported by pytype.
        utils.validate_version(version)
        self.output_options.python_version = version

        if utils.can_compile_bytecode_natively(
                self.output_options.python_version):
            # pytype does not need an exe for bytecode compilation. Abort early to
            # avoid extracting a large unused exe into /tmp.
            self.output_options.python_exe = None
            return

        for exe in utils.get_python_exes(self.output_options.python_version):
            exe_version = utils.get_python_exe_version(exe)
            if exe_version == self.output_options.python_version:
                self.output_options.python_exe = exe
                break
        else:
            self.error("Need a valid python%d.%d executable in $PATH" %
                       self.output_options.python_version)
コード例 #3
0
ファイル: pyc.py プロジェクト: zenefits/pytype
def compile_src_string_to_pyc_string(src,
                                     filename,
                                     python_version,
                                     python_exe: Tuple[List[str], List[str]],
                                     mode="exec"):
    """Compile Python source code to pyc data.

  This may use py_compile if the src is for the same version as we're running,
  or else it spawns an external process to produce a .pyc file. The generated
  bytecode (.pyc file) is read and both it and any temporary files are deleted.

  Args:
    src: Python sourcecode
    filename: Name of the source file. For error messages.
    python_version: Python version, (major, minor).
    python_exe: Tuple of a path to a Python interpreter and command-line flags.
    mode: Same as __builtin__.compile: "exec" if source consists of a
      sequence of statements, "eval" if it consists of a single expression,
      or "single" if it consists of a single interactive statement.

  Returns:
    The compiled pyc file as a binary string.
  Raises:
    CompileError: If we find a syntax error in the file.
    IOError: If our compile script failed.
  """

    if utils.can_compile_bytecode_natively(python_version):
        output = six.BytesIO()
        compile_bytecode.compile_src_to_pyc(src, filename or "<>", output,
                                            mode)
        bytecode = output.getvalue()
    else:
        tempfile_options = {"mode": "w", "suffix": ".py", "delete": False}
        if six.PY3:
            tempfile_options.update({"encoding": "utf-8"})
        else:
            tempfile_options.update({"mode": "wb"})
        fi = tempfile.NamedTemporaryFile(**tempfile_options)
        try:
            if six.PY3:
                fi.write(src)
            else:
                fi.write(src.encode("utf-8"))
            fi.close()
            # In order to be able to compile pyc files for a different Python version
            # from the one we're running under, we spawn an external process.
            # We pass -E to ignore the environment so that PYTHONPATH and
            # sitecustomize on some people's systems don't mess with the interpreter.
            exe, flags = python_exe
            cmd = exe + flags + ["-E", "-", fi.name, filename or fi.name, mode]

            compile_script_src = pytype_source_utils.load_pytype_file(
                COMPILE_SCRIPT)

            p = subprocess.Popen(cmd,
                                 stdin=subprocess.PIPE,
                                 stdout=subprocess.PIPE)
            bytecode, _ = p.communicate(compile_script_src)
            assert p.poll() == 0, "Child process failed"
        finally:
            os.unlink(fi.name)
    first_byte = six.indexbytes(bytecode, 0)
    if first_byte == 0:  # compile OK
        return bytecode[1:]
    elif first_byte == 1:  # compile error
        code = bytecode[1:]  # type: bytes
        raise CompileError(compat.native_str(code))
    else:
        raise IOError("_compile.py produced invalid result")