Skip to content

Conversation

@arrdem
Copy link
Collaborator

@arrdem arrdem commented Jun 4, 2025

Due to differences between the MacOS and Linux implementations of Bazel's sandboxing (reported as #573) the current implementation of manipulating argv[0] to make an interpreter see itself as having a path of .runfiles/.../.venv/bin/python3 isn't effective.

Specifically on Linux it appears that we're more eagerly resolving symlinks.

This means that bazel-bin/.../*.runfiles/*/.venv/bin/python3 is being immediately resolved to an /execroot/bazel-bin/... entry which contains only generated files. An interpreter with relative path based import roots within the execroot will be able to import relocated sources (copied into the venv) but will not be able to import from source files or external generated files.

Effectively spawning the interpreter is escaping the .runfiles tree which breaks a bunch of our other assumptions.

The repair is to come up with a more portable way to identify the interpreter without escaping from the runfiles sandbox.

As a solution this PR makes the interpreter shim depend both on the $VIRTUAL_ENV variable which also serves as an anchor to the "real" .runfiles tree. Due to the removals of realpath calls in the activate script, it's possible that we could provide fallback behavior by introspecting $0, but that verges on #581 so punting for now.


Changes are visible to end-users: no

Test plan

  • Add imports from unmodified sources to the test cases

@github-actions
Copy link

github-actions bot commented Jun 4, 2025

e2e/use_release folder: LCOV of commit 67f38e6 during CI #1850

Summary coverage rate:
  lines......: 100.0% (2 of 2 lines)
  functions..: 100.0% (1 of 1 function)
  branches...: no data found

Files changed coverage rate: n/a

@aspect-workflows
Copy link

aspect-workflows bot commented Jun 4, 2025

Test

8 test targets passed

Targets
//py/tests/py-external-venv:test [k8-fastbuild]                                           183ms
//py/tests/py-internal-venv:test [k8-fastbuild]                                           244ms
//py/tests/py_venv_conflict:validate_import_roots [k8-fastbuild]                          324ms
//py/tests/py_venv_image_layer:my_app_amd64_layers_test [k8-fastbuild]                    30ms
//py/tests/py_venv_image_layer:my_app_arm64_layers_test [k8-fastbuild]                    68ms
//py/tests/py_venv_image_layer:py_amd64_image_command_test [k8-fastbuild]                 447ms
//py/tests/py_venv_image_layer:py_amd64_image_content_test [k8-fastbuild]                 355ms
//py/tests/py_venv_image_layer:py_arm64_image_content_test [k8-fastbuild]                 406ms

Total test execution time was 2s. 32 tests (80.0%) were fully cached saving 1m 1s.

@arrdem arrdem changed the title test(py_venv): Assert re: relocations fix(py_venv): Repair runfiles-relative import roots Jun 5, 2025
@arrdem arrdem changed the title fix(py_venv): Repair runfiles-relative import roots fix(py_venv): Repair runfiles-relative venv roots Jun 9, 2025
@arrdem arrdem force-pushed the arrdem/573-repro branch from fdc0e9b to 24c2a0d Compare June 9, 2025 19:47
Copy link
Member

@thesayyn thesayyn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@arrdem arrdem merged commit 5ea06cb into main Jun 9, 2025
16 checks passed
@arrdem arrdem deleted the arrdem/573-repro branch June 9, 2025 21:30
@arrdem arrdem added this to the 1.6.0 milestone Jun 9, 2025
arrdem added a commit that referenced this pull request Jun 10, 2025
Identified in manual testing of v1.6.0-rc0.

Because of overly conservative removals of `realpath` in #579, an issue
is exposed where `$VIRTUAL_ENV` would be an un-resolved relative path
both under Bazel and more significantly once a user activates a linked
venv. This isn't so bad for binaries which usually don't `chdir`, but
it's a problem for shells.

Since MacOS doesn't ship a `realpath` which can be configured to ignore
symlinks, we can't just `realpath` the runfiles dir or the virtualenv
home. But once we've configured a Python interpreter what we can do is
use `os.path.abspath`. Unlike `realpath`, `abspath` does not attempt to
resolve symlink path segments. It just uses `normpath` to eliminate
relative path segments. This allows us to compute an absolute path in a
portable way, once we get an appropriate interpreter up and running.

---

### Changes are visible to end-users: no

### Test plan

- Manual testing; please provide instructions so we can reproduce:

```
❯ bazel run //examples/py_binary:py_binary.venv
INFO: Analyzed target //examples/py_binary:py_binary.venv (0 packages loaded, 0 targets configured).
INFO: Found 1 target...
Target //examples/py_binary:py_binary.venv up-to-date:
  bazel-bin/examples/py_binary/py_binary.venv
INFO: Elapsed time: 0.785s, Critical Path: 0.02s
INFO: 1 process: 1 internal.
INFO: Build completed successfully, 1 total action
INFO: Running command line: bazel-bin/examples/py_binary/py_binary.venv
Linking: /private/var/tmp/_bazel_arrdem/93bfea6cdc1153cc29a75400cd38823a/execroot/aspect_rules_py/bazel-out/darwin_arm64-fastbuild/bin/examples/py_binary/.py_binary.venv -> /Users/arrdem/Documents/work/aspect/rules_py/examples/py_binary/.py_binary.venv

To activate the virtualenv run:
    source /Users/arrdem/Documents/work/aspect/rules_py/examples/py_binary/.py_binary.venv/bin/activate

Link is up to date!

❯ source /Users/arrdem/Documents/work/aspect/rules_py/examples/py_binary/.py_binary.venv/bin/activate

❯ env | grep -e PYTHON -e RUNFILES -e VIRTUAL -e VENV | sort
PYTHONEXECUTABLE=/Users/arrdem/Documents/work/aspect/rules_py/examples/py_binary/.py_binary.venv/bin/python
PYTHONHOME=/private/var/tmp/_bazel_arrdem/93bfea6cdc1153cc29a75400cd38823a/execroot/aspect_rules_py/bazel-out/darwin_arm64-fastbuild/bin/examples/py_binary/py_binary.venv.runfiles/python_toolchain_aarch64-apple-darwin
RUNFILES_DIR=/private/var/tmp/_bazel_arrdem/93bfea6cdc1153cc29a75400cd38823a/execroot/aspect_rules_py/bazel-out/darwin_arm64-fastbuild/bin/examples/py_binary/py_binary.venv.runfiles
RUNFILES_MANIFEST_FILE=/private/var/tmp/_bazel_arrdem/93bfea6cdc1153cc29a75400cd38823a/execroot/aspect_rules_py/bazel-out/darwin_arm64-fastbuild/bin/examples/py_binary/py_binary.venv.runfiles/MANIFEST
RUNFILES_REPO_MAPPING=/private/var/tmp/_bazel_arrdem/93bfea6cdc1153cc29a75400cd38823a/execroot/aspect_rules_py/bazel-out/darwin_arm64-fastbuild/bin/examples/py_binary/py_binary.venv.runfiles/_repo_mapping
VIRTUAL_ENV_DISABLE_PROMPT=1
VIRTUAL_ENV=/Users/arrdem/Documents/work/aspect/rules_py/examples/py_binary/.py_binary.venv
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants