Avoid enumerating sources in errors for path Python requests (#13335)

e.g., these are misleading cruft in the error message at
https://github.com/astral-sh/uv/pull/12168#discussion_r2078204601

```
❯ uv python find /foo/bar
error: No interpreter found for path `/foo/bar` in virtual environments, managed installations, or search path
❯ cargo run -q -- python find /foo/bar
error: No interpreter found at path `/foo/bar`
```
This commit is contained in:
Zanie Blue 2025-05-07 13:53:09 -05:00 committed by GitHub
parent 364e3999d4
commit fa8db5a8d0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 61 additions and 2 deletions

View file

@ -2646,6 +2646,12 @@ impl fmt::Display for PythonNotFound {
PythonRequest::Default | PythonRequest::Any => { PythonRequest::Default | PythonRequest::Any => {
write!(f, "No interpreter found in {sources}") write!(f, "No interpreter found in {sources}")
} }
PythonRequest::File(_) => {
write!(f, "No interpreter found at {}", self.request)
}
PythonRequest::Directory(_) => {
write!(f, "No interpreter found in {}", self.request)
}
_ => { _ => {
write!(f, "No interpreter found for {} in {sources}", self.request) write!(f, "No interpreter found for {} in {sources}", self.request)
} }

View file

@ -293,6 +293,19 @@ impl TestContext {
self self
} }
/// Adds a filter for platform-specific errors when a file is not executable.
#[inline]
pub fn with_filtered_not_executable(mut self) -> Self {
let pattern = if cfg!(unix) {
r"Permission denied \(os error 13\)"
} else {
r"\%1 is not a valid Win32 application. \(os error 193\)"
};
self.filters
.push((pattern.to_string(), "[PERMISSION DENIED]".to_string()));
self
}
/// Adds a filter that ignores platform information in a Python installation key. /// Adds a filter that ignores platform information in a Python installation key.
pub fn with_filtered_python_keys(mut self) -> Self { pub fn with_filtered_python_keys(mut self) -> Self {
// Filter platform keys // Filter platform keys

View file

@ -17381,7 +17381,7 @@ fn compile_broken_active_venv() -> Result<()> {
----- stdout ----- ----- stdout -----
----- stderr ----- ----- stderr -----
× No interpreter found for path `python3.14159` in managed installations or search path × No interpreter found at path `python3.14159`
"); ");
// Simulate a removed Python interpreter // Simulate a removed Python interpreter

View file

@ -1,4 +1,4 @@
use assert_fs::prelude::PathChild; use assert_fs::prelude::{FileTouch, PathChild};
use assert_fs::{fixture::FileWriteStr, prelude::PathCreateDir}; use assert_fs::{fixture::FileWriteStr, prelude::PathCreateDir};
use indoc::indoc; use indoc::indoc;
@ -977,3 +977,43 @@ fn python_find_show_version() {
----- stderr ----- ----- stderr -----
"); ");
} }
#[test]
fn python_find_path() {
let context: TestContext = TestContext::new_with_versions(&[]).with_filtered_not_executable();
context.temp_dir.child("foo").create_dir_all().unwrap();
context.temp_dir.child("bar").touch().unwrap();
// No interpreter in a directory
uv_snapshot!(context.filters(), context.python_find().arg(context.temp_dir.child("foo").as_os_str()), @r"
success: false
exit_code: 2
----- stdout -----
----- stderr -----
error: No interpreter found in directory `foo`
");
// No interpreter at a file
uv_snapshot!(context.filters(), context.python_find().arg(context.temp_dir.child("bar").as_os_str()), @r"
success: false
exit_code: 2
----- stdout -----
----- stderr -----
error: Failed to inspect Python interpreter from provided path at `bar`
Caused by: Failed to query Python interpreter at `[TEMP_DIR]/bar`
Caused by: [PERMISSION DENIED]
");
// No interpreter at a file that does not exist
uv_snapshot!(context.filters(), context.python_find().arg(context.temp_dir.child("foobar").as_os_str()), @r"
success: false
exit_code: 2
----- stdout -----
----- stderr -----
error: No interpreter found at path `foobar`
");
}