diff --git a/crates/uv-static/src/env_vars.rs b/crates/uv-static/src/env_vars.rs index 1d054c6f6e803..3948eda7bce15 100644 --- a/crates/uv-static/src/env_vars.rs +++ b/crates/uv-static/src/env_vars.rs @@ -568,6 +568,12 @@ impl EnvVars { #[attr_added_in("0.9.15")] pub const UV_INTERNAL__TEST_LFS_DISABLED: &'static str = "UV_INTERNAL__TEST_LFS_DISABLED"; + /// Marker variable to track whether `PYTHONHOME` was set by uv. + /// Used by the Windows trampoline to distinguish uv-set values from user-set values. + #[attr_hidden] + #[attr_added_in("next release")] + pub const UV_INTERNAL__PYTHONHOME: &'static str = "UV_INTERNAL__PYTHONHOME"; + /// Path to system-level configuration directory on Unix systems. #[attr_added_in("0.4.26")] pub const XDG_CONFIG_DIRS: &'static str = "XDG_CONFIG_DIRS"; diff --git a/crates/uv-trampoline-builder/trampolines/uv-trampoline-aarch64-console.exe b/crates/uv-trampoline-builder/trampolines/uv-trampoline-aarch64-console.exe index 804e68d80c278..7e33bbaa7b223 100755 Binary files a/crates/uv-trampoline-builder/trampolines/uv-trampoline-aarch64-console.exe and b/crates/uv-trampoline-builder/trampolines/uv-trampoline-aarch64-console.exe differ diff --git a/crates/uv-trampoline-builder/trampolines/uv-trampoline-aarch64-gui.exe b/crates/uv-trampoline-builder/trampolines/uv-trampoline-aarch64-gui.exe index 7dbaa80a0dbf7..5355e550feed9 100755 Binary files a/crates/uv-trampoline-builder/trampolines/uv-trampoline-aarch64-gui.exe and b/crates/uv-trampoline-builder/trampolines/uv-trampoline-aarch64-gui.exe differ diff --git a/crates/uv-trampoline-builder/trampolines/uv-trampoline-i686-console.exe b/crates/uv-trampoline-builder/trampolines/uv-trampoline-i686-console.exe index 33f21a2b934e6..76317ecee6fb9 100755 Binary files a/crates/uv-trampoline-builder/trampolines/uv-trampoline-i686-console.exe and b/crates/uv-trampoline-builder/trampolines/uv-trampoline-i686-console.exe differ diff --git a/crates/uv-trampoline-builder/trampolines/uv-trampoline-i686-gui.exe b/crates/uv-trampoline-builder/trampolines/uv-trampoline-i686-gui.exe index 1e753c1fb4f95..23dab4f25c356 100755 Binary files a/crates/uv-trampoline-builder/trampolines/uv-trampoline-i686-gui.exe and b/crates/uv-trampoline-builder/trampolines/uv-trampoline-i686-gui.exe differ diff --git a/crates/uv-trampoline-builder/trampolines/uv-trampoline-x86_64-console.exe b/crates/uv-trampoline-builder/trampolines/uv-trampoline-x86_64-console.exe index a5a5ab6025785..36542006d7355 100755 Binary files a/crates/uv-trampoline-builder/trampolines/uv-trampoline-x86_64-console.exe and b/crates/uv-trampoline-builder/trampolines/uv-trampoline-x86_64-console.exe differ diff --git a/crates/uv-trampoline-builder/trampolines/uv-trampoline-x86_64-gui.exe b/crates/uv-trampoline-builder/trampolines/uv-trampoline-x86_64-gui.exe index 700fd94a649a3..0e8967ef6c127 100755 Binary files a/crates/uv-trampoline-builder/trampolines/uv-trampoline-x86_64-gui.exe and b/crates/uv-trampoline-builder/trampolines/uv-trampoline-x86_64-gui.exe differ diff --git a/crates/uv-trampoline/src/bounce.rs b/crates/uv-trampoline/src/bounce.rs index 761f5e4805565..d2cfb5fc01fd2 100644 --- a/crates/uv-trampoline/src/bounce.rs +++ b/crates/uv-trampoline/src/bounce.rs @@ -146,20 +146,35 @@ fn make_child_cmdline() -> CString { // be correctly detected when using trampolines. std::env::set_var(EnvVars::PYVENV_LAUNCHER, &executable_name); - // If this is not a virtual environment and `PYTHONHOME` has - // not been set, then set `PYTHONHOME` to the parent directory of - // the executable. This ensures that the correct installation - // directories are added to `sys.path` when running with a junction - // trampoline. - let python_home_set = - std::env::var(EnvVars::PYTHONHOME).is_ok_and(|home| !home.is_empty()); - if !is_virtualenv(python_exe.as_path()) && !python_home_set { - std::env::set_var( - EnvVars::PYTHONHOME, - python_exe + // If this is not a virtual environment, set `PYTHONHOME` to + // the parent directory of the executable. This ensures that + // the correct installation directories are added to `sys.path` + // when running with a junction trampoline. + // + // We use a marker variable (`UV_INTERNAL__PYTHONHOME`) to track + // whether `PYTHONHOME` was set by uv. This allows us to: + // - Override inherited `PYTHONHOME` from parent Python processes + // - Preserve user-defined `PYTHONHOME` values + if !is_virtualenv(python_exe.as_path()) { + let python_home = std::env::var(EnvVars::PYTHONHOME).ok(); + let marker = std::env::var(EnvVars::UV_INTERNAL__PYTHONHOME).ok(); + + // Only set `PYTHONHOME` if: + // - It's not set, OR + // - It was set by uv (marker matches current `PYTHONHOME`) + let should_override = match (&python_home, &marker) { + (None, _) => true, + (Some(home), Some(m)) if home == m => true, + _ => false, + }; + + if should_override { + let home = python_exe .parent() - .expect("Python executable should have a parent directory"), - ); + .expect("Python executable should have a parent directory"); + std::env::set_var(EnvVars::PYTHONHOME, home); + std::env::set_var(EnvVars::UV_INTERNAL__PYTHONHOME, home); + } } } }