From aa29eebc9c67d70d302375e3aa301d9c0127e7e4 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 8 Jan 2026 21:27:54 +0000 Subject: [PATCH] Support relative paths in override variables for `user_executable_directory` Use a plain `parse_path` for uv-specific override variables (like `UV_PYTHON_BIN_DIR` and `UV_TOOL_BIN_DIR`) that accepts both relative and absolute paths, while keeping `parse_xdg_path` for XDG standard variables to comply with the XDG Base Directory Specification. Closes #17364 --- crates/uv-dirs/src/lib.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/crates/uv-dirs/src/lib.rs b/crates/uv-dirs/src/lib.rs index f55e842928d92..7274d6276abf6 100644 --- a/crates/uv-dirs/src/lib.rs +++ b/crates/uv-dirs/src/lib.rs @@ -24,7 +24,7 @@ use uv_static::EnvVars; pub fn user_executable_directory(override_variable: Option<&'static str>) -> Option { override_variable .and_then(std::env::var_os) - .and_then(parse_xdg_path) + .and_then(parse_path) .or_else(|| std::env::var_os(EnvVars::XDG_BIN_HOME).and_then(parse_xdg_path)) .or_else(|| { std::env::var_os(EnvVars::XDG_DATA_HOME) @@ -83,6 +83,18 @@ pub fn legacy_user_state_dir() -> Option { .map(|dir| if cfg!(windows) { dir.join("data") } else { dir }) } +/// Return a [`PathBuf`] from the given [`OsString`], if non-empty. +/// +/// Unlike [`parse_xdg_path`], this function accepts both relative and absolute paths, +/// for use with uv-specific override variables that are not subject to the XDG specification. +fn parse_path(path: OsString) -> Option { + if path.is_empty() { + None + } else { + Some(PathBuf::from(path)) + } +} + /// Return a [`PathBuf`] if the given [`OsString`] is an absolute path. /// /// Relative paths are considered invalid per the [XDG Base Directory Specification]: