Ejemplo n.º 1
0
async def find_interpreter(
        interpreter_constraints: InterpreterConstraints,
        pex_runtime_env: PexRuntimeEnvironment) -> PythonExecutable:
    formatted_constraints = " OR ".join(
        str(constraint) for constraint in interpreter_constraints)
    result = await Get(
        ProcessResult,
        PexCliProcess(
            description=
            f"Find interpreter for constraints: {formatted_constraints}",
            subcommand=(),
            # Here, we run the Pex CLI with no requirements, which just selects an interpreter.
            # Normally, this would start an isolated repl. By passing `--`, we force the repl to
            # instead act as an interpreter (the selected one) and tell us about itself. The upshot
            # is we run the Pex interpreter selection logic unperturbed but without resolving any
            # distributions.
            extra_args=(
                *interpreter_constraints.generate_pex_arg_list(),
                "--",
                "-c",
                # N.B.: The following code snippet must be compatible with Python 2.7 and
                # Python 3.5+.
                #
                # When hashing, we pick 8192 for efficiency of reads and fingerprint updates
                # (writes) since it's a common OS buffer size and an even multiple of the
                # hash block size.
                dedent("""\
                    import hashlib, os, sys

                    python = os.path.realpath(sys.executable)
                    print(python)

                    hasher = hashlib.sha256()
                    with open(python, "rb") as fp:
                      for chunk in iter(lambda: fp.read(8192), b""):
                          hasher.update(chunk)
                    print(hasher.hexdigest())
                    """),
            ),
            level=LogLevel.DEBUG,
            # NB: We want interpreter discovery to re-run fairly frequently
            # (PER_RESTART_SUCCESSFUL), but not on every run of Pants (NEVER, which is effectively
            # per-Session). See #10769 for a solution that is less of a tradeoff.
            cache_scope=ProcessCacheScope.PER_RESTART_SUCCESSFUL,
        ),
    )
    path, fingerprint = result.stdout.decode().strip().splitlines()

    if pex_runtime_env.verbosity > 0:
        log_output = result.stderr.decode()
        if log_output:
            logger.info("%s", log_output)

    return PythonExecutable(path=path, fingerprint=fingerprint)
Ejemplo n.º 2
0
async def find_interpreter(
        interpreter_constraints: PexInterpreterConstraints
) -> PythonExecutable:
    formatted_constraints = " OR ".join(
        str(constraint) for constraint in interpreter_constraints)
    process = await Get(
        Process,
        PexCliProcess(
            description=
            f"Find interpreter for constraints: {formatted_constraints}",
            # Here, we run the Pex CLI with no requirements, which just selects an interpreter.
            # Normally, this would start an isolated repl. By passing `--`, we force the repl to
            # instead act as an interpreter (the selected one) and tell us about itself. The upshot
            # is we run the Pex interpreter selection logic unperturbed but without resolving any
            # distributions.
            argv=(
                *interpreter_constraints.generate_pex_arg_list(),
                "--",
                "-c",
                # N.B.: The following code snippet must be compatible with Python 2.7 and
                # Python 3.5+.
                dedent("""\
                    import hashlib
                    import os
                    import sys

                    python = os.path.realpath(sys.executable)
                    print(python)

                    hasher = hashlib.sha256()
                    with open(python, "rb") as fp:
                      # We pick 8192 for efficiency of reads and fingerprint updates
                      # (writes) since it's a common OS buffer size and an even
                      # multiple of the hash block size.
                      for chunk in iter(lambda: fp.read(8192), b""):
                          hasher.update(chunk)
                    print(hasher.hexdigest())
                    """),
            ),
            level=LogLevel.DEBUG,
        ),
    )
    result = await Get(
        ProcessResult,
        UncacheableProcess(process=process, scope=ProcessScope.PER_SESSION))
    path, fingerprint = result.stdout.decode().strip().splitlines()
    return PythonExecutable(path=path, fingerprint=fingerprint)