diff --git a/crates/uv-python/src/discovery.rs b/crates/uv-python/src/discovery.rs index fb2033ada..217606ae1 100644 --- a/crates/uv-python/src/discovery.rs +++ b/crates/uv-python/src/discovery.rs @@ -1013,6 +1013,13 @@ impl Error { ); false } + InterpreterError::PermissionDenied { path, err } => { + debug!( + "Skipping unexecutable interpreter at {} from {source}: {err}", + path.display() + ); + false + } InterpreterError::NotFound(path) | InterpreterError::BrokenSymlink(BrokenSymlink { path, .. }) => { // If the interpreter is from an active, valid virtual environment, we should diff --git a/crates/uv-python/src/interpreter.rs b/crates/uv-python/src/interpreter.rs index 4c04d844b..8469f05f1 100644 --- a/crates/uv-python/src/interpreter.rs +++ b/crates/uv-python/src/interpreter.rs @@ -797,6 +797,12 @@ pub enum Error { #[source] err: io::Error, }, + #[error("Failed to query Python interpreter at `{path}`")] + PermissionDenied { + path: PathBuf, + #[source] + err: io::Error, + }, #[error("{0}")] UnexpectedResponse(UnexpectedResponseError), #[error("{0}")] @@ -911,8 +917,15 @@ impl InterpreterInfo { .arg(script) .output() .map_err(|err| { - if err.kind() == io::ErrorKind::NotFound { - return Error::NotFound(interpreter.to_path_buf()); + match err.kind() { + io::ErrorKind::NotFound => return Error::NotFound(interpreter.to_path_buf()), + io::ErrorKind::PermissionDenied => { + return Error::PermissionDenied { + path: interpreter.to_path_buf(), + err, + }; + } + _ => {} } #[cfg(windows)] if let Some(APPMODEL_ERROR_NO_PACKAGE | ERROR_CANT_ACCESS_FILE) =