# Buggy code
async def find_pex_python(
    python_setup: PythonSetup,
    pex_runtime_env: PexRuntimeEnvironment,
    subprocess_env_vars: SubprocessEnvironmentVars,
) -> PexEnvironment:
    # PEX files are compatible with bootstrapping via Python 2.7 or Python 3.5+. The bootstrap
    # code will then re-exec itself if the underlying PEX user code needs a more specific python
    # interpreter. As such, we look for many Pythons usable by the PEX bootstrap code here for
    # maximum flexibility.
    all_python_binary_paths = await MultiGet(
        [
            Get(
                BinaryPaths,
                BinaryPathRequest(
                    search_path=python_setup.interpreter_search_paths,
                    binary_name=binary_name,
                    test_args=[
                        "-c",
                        # N.B.: The following code snippet must be compatible with Python 2.7 and
                        # Python 3.5+.
                        dedent(
                            """\
                            import sys

                            major, minor = sys.version_info[:2]
                            if (major, minor) == (2, 7) or (major == 3 and minor >= 5):
                                # Here we hash the underlying python interpreter executable to
                                # ensure we detect changes in the real interpreter that might
                                # otherwise be masked by pyenv shim scripts found on the search
                                # path. Naively, just printing out the full version_info would be
                                # enough, but that does not account for supported abi changes (e.g.:
                                # a pyenv switch from a py27mu interpreter to a py27m interpreter.
                                import hashlib
                                hasher = hashlib.sha256()
                                with open(sys.executable, "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)
                                sys.stdout.write(hasher.hexdigest())
                                sys.exit(0)
                            else:
                                sys.exit(1)
                            """
                        ),
                    ],
                ),
            )
            for binary_name in pex_runtime_env.bootstrap_interpreter_names
        ]
    )

    def first_python_binary() -> Optional[str]:
        for binary_paths in all_python_binary_paths:
            if binary_paths.first_path:
                return binary_paths.first_path.path
        return None

    return PexEnvironment(
        path=pex_runtime_env.path,
        interpreter_search_paths=tuple(python_setup.interpreter_search_paths),
        subprocess_environment_dict=subprocess_env_vars.vars,
        bootstrap_python=first_python_binary(),
    )


# Traceback (pants.engine.internals.scheduler.ExecutionError)
$ ./pants fmt src/python/pants::
Compiling engine v0.0.1 (XXX)
Finished release [optimized + debuginfo] target(s) in 2m 49s
12:11:49 [INFO] initializing pantsd...
12:12:00 [INFO] pantsd initialized.
12:12:08.46 [INFO] Completed: Building black.pex with 2 requirements: black==19.10b0, setuptools
12:12:08 [WARN] /Users/tdyas/TC/pants/src/python/pants/base/exception_sink.py:359: DeprecationWarning: PY_SSIZE_T_CLEAN will be required for '#' formats
process_title=setproctitle.getproctitle(),

12:12:08 [ERROR] 1 Exception encountered:

Engine traceback:
in select
in `fmt` goal
in pants.backend.python.lint.python_fmt.format_python_target
in Format with Black
in pants.engine.process.fallible_to_exec_result_or_raise
Traceback (most recent call last):
File "XXX/pants/src/python/pants/engine/process.py", line 229, in fallible_to_exec_result_or_raise
raise ProcessExecutionFailure(
pants.engine.process.ProcessExecutionFailure: Process 'Run Black on 413 files.' failed with exit code 127.
stdout:

stderr:
env: python3.7: No such file or directory

Traceback (most recent call last):
File "XXX/pants/src/python/pants/bin/local_pants_runner.py", line 255, in run
engine_result = self._run_v2()
File "XXX/pants/src/python/pants/bin/local_pants_runner.py", line 166, in _run_v2
return self._maybe_run_v2_body(goals, poll=False)
File "XXX/pants/src/python/pants/bin/local_pants_runner.py", line 183, in _maybe_run_v2_body
return self.graph_session.run_goal_rules(
File "XXX/pants/src/python/pants/init/engine_initializer.py", line 117, in run_goal_rules
exit_code = self.scheduler_session.run_goal_rule(
File "XXX/pants/src/python/pants/engine/internals/scheduler.py", line 552, in run_goal_rule
self._raise_on_error([t for _, t in throws])
File "XXX/pants/src/python/pants/engine/internals/scheduler.py", line 511, in _raise_on_error
raise ExecutionError(
pants.engine.internals.scheduler.ExecutionError: 1 Exception encountered:

Engine traceback:
in select
in `fmt` goal
in pants.backend.python.lint.python_fmt.format_python_target
in Format with Black
in pants.engine.process.fallible_to_exec_result_or_raise
Traceback (most recent call last):
File "XXX/pants/src/python/pants/engine/process.py", line 229, in fallible_to_exec_result_or_raise
raise ProcessExecutionFailure(
pants.engine.process.ProcessExecutionFailure: Process 'Run Black on 413 files.' failed with exit code 127.
stdout:

stderr:
env: python3.7: No such file or directory

# Fixed code
async def find_pex_python(
    python_setup: PythonSetup,
    pex_runtime_env: PexRuntimeEnvironment,
    subprocess_env_vars: SubprocessEnvironmentVars,
) -> PexEnvironment:
    # PEX files are compatible with bootstrapping via Python 2.7 or Python 3.5+. The bootstrap
    # code will then re-exec itself if the underlying PEX user code needs a more specific python
    # interpreter. As such, we look for many Pythons usable by the PEX bootstrap code here for
    # maximum flexibility.
    all_python_binary_paths = await MultiGet(
        Get(
            BinaryPaths,
            BinaryPathRequest(
                search_path=python_setup.interpreter_search_paths,
                binary_name=binary_name,
                test=BinaryPathTest(
                    args=[
                        "-c",
                        # N.B.: The following code snippet must be compatible with Python 2.7 and
                        # Python 3.5+.
                        dedent(
                            """\
                            import sys

                            major, minor = sys.version_info[:2]
                            if (major, minor) == (2, 7) or (major == 3 and minor >= 5):
                                # Here we hash the underlying python interpreter executable to
                                # ensure we detect changes in the real interpreter that might
                                # otherwise be masked by pyenv shim scripts found on the search
                                # path. Naively, just printing out the full version_info would be
                                # enough, but that does not account for supported abi changes (e.g.:
                                # a pyenv switch from a py27mu interpreter to a py27m interpreter.
                                import hashlib
                                hasher = hashlib.sha256()
                                with open(sys.executable, "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)
                                sys.stdout.write(hasher.hexdigest())
                                sys.exit(0)
                            else:
                                sys.exit(1)
                            """
                        ),
                    ],
                    fingerprint_stdout=False,  # We already emit a usable fingerprint to stdout.
                ),
            ),
        )
        for binary_name in pex_runtime_env.bootstrap_interpreter_names
    )

    def first_python_binary() -> Optional[PythonExecutable]:
        for binary_paths in all_python_binary_paths:
            if binary_paths.first_path:
                return PythonExecutable(
                    path=binary_paths.first_path.path,
                    fingerprint=binary_paths.first_path.fingerprint,
                )
        return None

    return PexEnvironment(
        path=pex_runtime_env.path,
        interpreter_search_paths=tuple(python_setup.interpreter_search_paths),
        subprocess_environment_dict=subprocess_env_vars.vars,
        bootstrap_python=first_python_binary(),
    )