Skip to content

Commit 8a557da

Browse files
authored
fix(py_venv): Partially resolve PYTHONHOME (#668)
Use the partially resolved interpreter path (eg. the first partially resolved path for the interpreter binary which is under `.runfiles/`) as the basis from which to identify the `pyvenv.cfg` file and thus as the `sys.prefix`. This fixes an issue which would allow the interpreter to observe an un-resolved `sys.prefix` relative to which `_aspect.pth` source imports would be invalid. Fixes #666. ### Changes are visible to end-users: yes - Searched for relevant documentation and updated as needed: yes - Breaking change (forces users to change their own code or config): no - Suggested release notes appear below: yes Fixed a bug which would prevent 1stparty and other relative imports from working as desired when venvs are consumed outside of Bazel. ### Test plan - Manual testing; please provide instructions so we can reproduce: Using `chicagotrading/shorty` at `venv-bug-repro`, ``` ❯ git diff | cat diff --git a/MODULE.bazel b/MODULE.bazel index 5f63c5f..b8d3dea 100755 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -20,3 +20,8 @@ python = use_extension("@rules_python//python/extensions:python.bzl", "python") python.toolchain( python_version = "3.12", ) + +local_path_override( + module_name = "aspect_rules_py", + path = "/Users/arrdem/Documents/work/aspect/rules_py", +) ❯ bazel run //app:app_bin.venv INFO: Analyzed target //app:app_bin.venv (1 packages loaded, 876 targets configured). INFO: Found 1 target... Target //app:app_bin.venv up-to-date: bazel-bin/app/app_bin.venv INFO: Elapsed time: 1.056s, Critical Path: 0.02s INFO: 1 process: 577 action cache hit, 1 internal. INFO: Build completed successfully, 1 total action INFO: Running command line: bazel-bin/app/app_bin.venv final "/private/var/tmp/_bazel_arrdem/6292cdb66616265d0039b3e456edaa70/execroot/_main/bazel-out/darwin_arm64-fastbuild/bin/app/app_bin.venv.runfiles/_main/app/.app_bin.venv/bin/python" [aspect] venv root "/private/var/tmp/_bazel_arrdem/6292cdb66616265d0039b3e456edaa70/execroot/_main/bazel-out/darwin_arm64-fastbuild/bin/app/app_bin.venv.runfiles/_main/app/.app_bin.venv" venv.cfg "/private/var/tmp/_bazel_arrdem/6292cdb66616265d0039b3e456edaa70/execroot/_main/bazel-out/darwin_arm64-fastbuild/bin/app/app_bin.venv.runfiles/_main/app/.app_bin.venv/pyvenv.cfg" [aspect] PyCfg { root: "/private/var/tmp/_bazel_arrdem/6292cdb66616265d0039b3e456edaa70/execroot/_main/bazel-out/darwin_arm64-fastbuild/bin/app/app_bin.venv.runfiles/_main/app/.app_bin.venv", cfg: "/private/var/tmp/_bazel_arrdem/6292cdb66616265d0039b3e456edaa70/execroot/_main/bazel-out/darwin_arm64-fastbuild/bin/app/app_bin.venv.runfiles/_main/app/.app_bin.venv/pyvenv.cfg", version_info: "3.12.0", interpreter: Runfiles { rpath: "rules_python++python+python_3_12_aarch64-apple-darwin/bin/python3", repo: "_main" }, user_site: false } [aspect] "/private/var/tmp/_bazel_arrdem/6292cdb66616265d0039b3e456edaa70/execroot/_main/bazel-out/darwin_arm64-fastbuild/bin/app/app_bin.venv.runfiles/_main/app/.app_bin.venv/bin/python3" [aspect] Attempting to execute: "/private/var/tmp/_bazel_arrdem/6292cdb66616265d0039b3e456edaa70/external/rules_python++python+python_3_12_aarch64-apple-darwin/bin/python3" with argv[0] as "/private/var/tmp/_bazel_arrdem/6292cdb66616265d0039b3e456edaa70/execroot/_main/bazel-out/darwin_arm64-fastbuild/bin/app/app_bin.venv.runfiles/_main/app/.app_bin.venv/bin/python3" and args as ["-B", "/private/var/tmp/_bazel_arrdem/6292cdb66616265d0039b3e456edaa70/execroot/_main/bazel-out/darwin_arm64-fastbuild/bin/app/app_bin.venv.runfiles/aspect_rules_py+/py/private/py_venv/link.py"] Linking: /private/var/tmp/_bazel_arrdem/6292cdb66616265d0039b3e456edaa70/execroot/_main/bazel-out/darwin_arm64-fastbuild/bin/app/app_bin.venv.runfiles/_main/app/.app_bin.venv -> /Users/arrdem/Documents/work/aspect/clients/chicago-trading/shorty/.app+app_bin.venv Link is up to date! To configure the virtualenv in your IDE, configure an interpreter with the homedir /Users/arrdem/Documents/work/aspect/clients/chicago-trading/shorty/.app+app_bin.venv Please note that you may encounter issues if your editor doesn't evaluate the `activate` script. If you do please file an issue at https://github.com/aspect-build/rules_py/issues/new?template=BUG-REPORT.yaml To activate the virtualenv in your shell run source /Users/arrdem/Documents/work/aspect/clients/chicago-trading/shorty/.app+app_bin.venv/bin/activate virtualenvwrapper users may further want to $ ln -s /Users/arrdem/Documents/work/aspect/clients/chicago-trading/shorty/.app+app_bin.venv $WORKON_HOME/.app+app_bin.venv ❯ source .app+app_bin.venv/bin/activate ❯ python3 -m app final "/private/var/tmp/_bazel_arrdem/6292cdb66616265d0039b3e456edaa70/execroot/_main/bazel-out/darwin_arm64-fastbuild/bin/app/app_bin.venv.runfiles/_main/app/.app_bin.venv/bin/python3" [aspect] venv root "/private/var/tmp/_bazel_arrdem/6292cdb66616265d0039b3e456edaa70/execroot/_main/bazel-out/darwin_arm64-fastbuild/bin/app/app_bin.venv.runfiles/_main/app/.app_bin.venv" venv.cfg "/private/var/tmp/_bazel_arrdem/6292cdb66616265d0039b3e456edaa70/execroot/_main/bazel-out/darwin_arm64-fastbuild/bin/app/app_bin.venv.runfiles/_main/app/.app_bin.venv/pyvenv.cfg" [aspect] PyCfg { root: "/private/var/tmp/_bazel_arrdem/6292cdb66616265d0039b3e456edaa70/execroot/_main/bazel-out/darwin_arm64-fastbuild/bin/app/app_bin.venv.runfiles/_main/app/.app_bin.venv", cfg: "/private/var/tmp/_bazel_arrdem/6292cdb66616265d0039b3e456edaa70/execroot/_main/bazel-out/darwin_arm64-fastbuild/bin/app/app_bin.venv.runfiles/_main/app/.app_bin.venv/pyvenv.cfg", version_info: "3.12.0", interpreter: Runfiles { rpath: "rules_python++python+python_3_12_aarch64-apple-darwin/bin/python3", repo: "_main" }, user_site: false } [aspect] "/private/var/tmp/_bazel_arrdem/6292cdb66616265d0039b3e456edaa70/execroot/_main/bazel-out/darwin_arm64-fastbuild/bin/app/app_bin.venv.runfiles/_main/app/.app_bin.venv/bin/python3" [aspect] Attempting to execute: "/private/var/tmp/_bazel_arrdem/6292cdb66616265d0039b3e456edaa70/external/rules_python++python+python_3_12_aarch64-apple-darwin/bin/python3" with argv[0] as "/private/var/tmp/_bazel_arrdem/6292cdb66616265d0039b3e456edaa70/execroot/_main/bazel-out/darwin_arm64-fastbuild/bin/app/app_bin.venv.runfiles/_main/app/.app_bin.venv/bin/python3" and args as ["-m", "app"] hi from foo_lib Hi from __main__ ❯ python3 -P -m app final "/private/var/tmp/_bazel_arrdem/6292cdb66616265d0039b3e456edaa70/execroot/_main/bazel-out/darwin_arm64-fastbuild/bin/app/app_bin.venv.runfiles/_main/app/.app_bin.venv/bin/python3" [aspect] venv root "/private/var/tmp/_bazel_arrdem/6292cdb66616265d0039b3e456edaa70/execroot/_main/bazel-out/darwin_arm64-fastbuild/bin/app/app_bin.venv.runfiles/_main/app/.app_bin.venv" venv.cfg "/private/var/tmp/_bazel_arrdem/6292cdb66616265d0039b3e456edaa70/execroot/_main/bazel-out/darwin_arm64-fastbuild/bin/app/app_bin.venv.runfiles/_main/app/.app_bin.venv/pyvenv.cfg" [aspect] PyCfg { root: "/private/var/tmp/_bazel_arrdem/6292cdb66616265d0039b3e456edaa70/execroot/_main/bazel-out/darwin_arm64-fastbuild/bin/app/app_bin.venv.runfiles/_main/app/.app_bin.venv", cfg: "/private/var/tmp/_bazel_arrdem/6292cdb66616265d0039b3e456edaa70/execroot/_main/bazel-out/darwin_arm64-fastbuild/bin/app/app_bin.venv.runfiles/_main/app/.app_bin.venv/pyvenv.cfg", version_info: "3.12.0", interpreter: Runfiles { rpath: "rules_python++python+python_3_12_aarch64-apple-darwin/bin/python3", repo: "_main" }, user_site: false } [aspect] "/private/var/tmp/_bazel_arrdem/6292cdb66616265d0039b3e456edaa70/execroot/_main/bazel-out/darwin_arm64-fastbuild/bin/app/app_bin.venv.runfiles/_main/app/.app_bin.venv/bin/python3" [aspect] Attempting to execute: "/private/var/tmp/_bazel_arrdem/6292cdb66616265d0039b3e456edaa70/external/rules_python++python+python_3_12_aarch64-apple-darwin/bin/python3" with argv[0] as "/private/var/tmp/_bazel_arrdem/6292cdb66616265d0039b3e456edaa70/execroot/_main/bazel-out/darwin_arm64-fastbuild/bin/app/app_bin.venv.runfiles/_main/app/.app_bin.venv/bin/python3" and args as ["-P", "-m", "app"] hi from foo_lib Hi from __main__ ```
1 parent 1445956 commit 8a557da

File tree

2 files changed

+22
-18
lines changed

2 files changed

+22
-18
lines changed

py/defs.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ def _py_binary_or_test(name, rule, srcs, main, data = [], deps = [], resolutions
9393

9494
_py_venv_link(
9595
name = "{}.venv".format(name),
96+
srcs = srcs,
9697
data = data,
9798
deps = deps,
9899
imports = kwargs.get("imports"),

py/tools/venv_shim/src/main.rs

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,6 @@ use std::process::Command;
1212
const PYVENV: &str = "pyvenv.cfg";
1313

1414
fn find_venv_root(exec_name: impl AsRef<Path>) -> miette::Result<(PathBuf, PathBuf)> {
15-
if let Ok(it) = env::var("VIRTUAL_ENV") {
16-
let root = PathBuf::from(it);
17-
let cfg = root.join(PYVENV);
18-
if cfg.exists() {
19-
return Ok((root, cfg));
20-
} else {
21-
eprintln!("Warning: $VIRTUAL_ENV is set but seems to be invalid; ignoring")
22-
}
23-
}
24-
2515
let exec_name = exec_name.as_ref().to_owned();
2616
if let Some(parent) = exec_name.parent().and_then(|it| it.parent()) {
2717
let cfg = parent.join(PYVENV);
@@ -216,13 +206,6 @@ fn main() -> miette::Result<()> {
216206
miette::bail!("could not discover an execution command-line");
217207
};
218208

219-
let (venv_root, venv_cfg) = find_venv_root(exec_name)?;
220-
221-
let venv_config = parse_venv_cfg(&venv_root, &venv_cfg)?;
222-
223-
// The logical path of the interpreter
224-
let venv_interpreter = venv_root.join("bin/python3");
225-
226209
// Alright this is a bit of a mess.
227210
//
228211
// There is a std::env::current_exe(), but it has platform dependent
@@ -305,7 +288,24 @@ fn main() -> miette::Result<()> {
305288

306289
#[cfg(feature = "debug")]
307290
eprintln!("final {:?}", executable);
308-
let actual_interpreter = find_actual_interpreter(executable, &venv_config)?;
291+
292+
// Now that we've identified where the .runfiles venv really is, we want to
293+
// use that as the basis for configuring our virtualenv and setting
294+
// everything else up.
295+
let (venv_root, venv_cfg) = find_venv_root(&executable)?;
296+
#[cfg(feature = "debug")]
297+
eprintln!("[aspect] venv root {:?} venv.cfg {:?}", venv_root, venv_cfg);
298+
299+
let venv_config = parse_venv_cfg(&venv_root, &venv_cfg)?;
300+
#[cfg(feature = "debug")]
301+
eprintln!("[aspect] {:?}", venv_config);
302+
303+
// The logical path of the interpreter
304+
let venv_interpreter = venv_root.join("bin/python3");
305+
#[cfg(feature = "debug")]
306+
eprintln!("[aspect] {:?}", venv_interpreter);
307+
308+
let actual_interpreter = find_actual_interpreter(&executable, &venv_config)?;
309309

310310
#[cfg(feature = "debug")]
311311
eprintln!(
@@ -347,6 +347,9 @@ fn main() -> miette::Result<()> {
347347
// Set the executable pointer for MacOS, but we do it consistently
348348
cmd.env("PYTHONEXECUTABLE", &venv_interpreter);
349349

350+
// Clobber VIRTUAL_ENV which may have been set by activate to an unresolved path
351+
cmd.env("VIRTUAL_ENV", &venv_root);
352+
350353
// Similar to `-s` but this avoids us having to muck with the argv in ways
351354
// that could be visible to the called program.
352355
if !venv_config.user_site {

0 commit comments

Comments
 (0)