Repository: pantsbuild/pants

Issue:
`No such file or directory: 'local_dists.pex/PEX-INFO'` when running a `python_source`
**Describe the bug**

After updating one of our CI checks to `./pants run` a `python_source` directly (vs. the previous code which ran the `pex_binary`), some of our jobs started failing with:
```
Traceback (most recent call last):
  File "/opt/python/3.8.14/lib/python3.8/runpy.py", line 194, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/opt/python/3.8.14/lib/python3.8/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/home/runner/.pants/execution/pants-sandbox-g6NiAf/./src.pex/__main__.py", line 89, in <module>
    __venv_dir__ = __maybe_run_venv__(
  File "/home/runner/.pants/execution/pants-sandbox-g6NiAf/./src.pex/__main__.py", line 37, in __maybe_run_venv__
    venv_dir = venv_dir(
  File "/home/runner/.pants/execution/pants-sandbox-g6NiAf/src.pex/.bootstrap/pex/variables.py", line 738, in venv_dir
  File "/home/runner/.pants/execution/pants-sandbox-g6NiAf/src.pex/.bootstrap/pex/variables.py", line 736, in add_pex_path_items
  File "/home/runner/.pants/execution/pants-sandbox-g6NiAf/src.pex/.bootstrap/pex/pex_info.py", line 82, in from_pex
FileNotFoundError: [Errno 2] No such file or directory: 'local_dists.pex/PEX-INFO'
```

The `python_source` has `run_goal_use_sandbox=False`.

**Pants version**

v2.15.0rc1

**OS**

Linux



Discussion:

Resolving patch:
diff --git a/src/python/pants/backend/python/goals/run_helper.py b/src/python/pants/backend/python/goals/run_helper.py
--- a/src/python/pants/backend/python/goals/run_helper.py
+++ b/src/python/pants/backend/python/goals/run_helper.py
@@ -14,14 +14,9 @@
     ResolvedPexEntryPoint,
     ResolvePexEntryPointRequest,
 )
-from pants.backend.python.util_rules.interpreter_constraints import InterpreterConstraints
-from pants.backend.python.util_rules.local_dists import LocalDistsPex, LocalDistsPexRequest
 from pants.backend.python.util_rules.pex import Pex, PexRequest, VenvPex, VenvPexRequest
 from pants.backend.python.util_rules.pex_environment import PexEnvironment
-from pants.backend.python.util_rules.pex_from_targets import (
-    InterpreterConstraintsRequest,
-    PexFromTargetsRequest,
-)
+from pants.backend.python.util_rules.pex_from_targets import PexFromTargetsRequest
 from pants.backend.python.util_rules.python_sources import (
     PythonSourceFiles,
     PythonSourceFilesRequest,
@@ -49,8 +44,7 @@ async def _create_python_source_run_request(
     console_script: Optional[ConsoleScript] = None,
 ) -> RunRequest:
     addresses = [address]
-    interpreter_constraints, entry_point, transitive_targets = await MultiGet(
-        Get(InterpreterConstraints, InterpreterConstraintsRequest(addresses)),
+    entry_point, transitive_targets = await MultiGet(
         Get(
             ResolvedPexEntryPoint,
             ResolvePexEntryPointRequest(entry_point_field),
@@ -70,6 +64,7 @@ async def _create_python_source_run_request(
                 output_filename=f"{pex_filename}.pex",
                 internal_only=True,
                 include_source_files=False,
+                include_local_dists=True,
                 # `PEX_EXTRA_SYS_PATH` should contain this entry_point's module.
                 main=console_script or entry_point.val,
                 additional_args=(
@@ -86,18 +81,7 @@ async def _create_python_source_run_request(
         ),
     )
 
-    local_dists = await Get(
-        LocalDistsPex,
-        LocalDistsPexRequest(
-            addresses,
-            internal_only=True,
-            interpreter_constraints=interpreter_constraints,
-            sources=sources,
-        ),
-    )
-    pex_request = dataclasses.replace(
-        pex_request, pex_path=(*pex_request.pex_path, local_dists.pex, *pex_path)
-    )
+    pex_request = dataclasses.replace(pex_request, pex_path=(*pex_request.pex_path, *pex_path))
 
     if run_in_sandbox:
         # Note that a RunRequest always expects to run directly in the sandbox/workspace
@@ -114,7 +98,7 @@ async def _create_python_source_run_request(
         # complexity of figuring out here which sources were codegenned, we copy everything.
         # The inline source roots precede the chrooted ones in PEX_EXTRA_SYS_PATH, so the inline
         # sources will take precedence and their copies in the chroot will be ignored.
-        local_dists.remaining_sources.source_files.snapshot.digest,
+        sources.source_files.snapshot.digest,
     ]
     merged_digest = await Get(Digest, MergeDigests(input_digests))
 


Test patch: