Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions crates/uv-python/src/discovery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2646,6 +2646,12 @@ impl fmt::Display for PythonNotFound {
PythonRequest::Default | PythonRequest::Any => {
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)
}
Expand Down
13 changes: 13 additions & 0 deletions crates/uv/tests/it/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,19 @@ impl TestContext {
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.
pub fn with_filtered_python_keys(mut self) -> Self {
// Filter platform keys
Expand Down
2 changes: 1 addition & 1 deletion crates/uv/tests/it/pip_compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17381,7 +17381,7 @@ fn compile_broken_active_venv() -> Result<()> {
----- stdout -----

----- 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
Expand Down
42 changes: 41 additions & 1 deletion crates/uv/tests/it/python_find.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use assert_fs::prelude::PathChild;
use assert_fs::prelude::{FileTouch, PathChild};
use assert_fs::{fixture::FileWriteStr, prelude::PathCreateDir};
use indoc::indoc;

Expand Down Expand Up @@ -977,3 +977,43 @@ fn python_find_show_version() {
----- 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`
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably show absolute paths here? Can be separate though.

");

// 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`
");
}
Loading