Skip to content

Commit

Permalink
Skip missing interpreters during discovery
Browse files Browse the repository at this point in the history
This feels kind of obvious, but the query code never checked if the requested interpreter exists so we would fail with an IO error and stop discovery which does not feel quite right
  • Loading branch information
zanieb committed Jun 10, 2024
1 parent d9f2c71 commit fa1a488
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 49 deletions.
4 changes: 4 additions & 0 deletions crates/uv-toolchain/src/discovery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,10 @@ fn should_stop_discovery(err: &Error) -> bool {
trace!("Skipping bad interpreter at {}", path.display());
false
}
InterpreterError::NotFound(path) => {
trace!("Skipping missing interpreter at {}", path.display());
false
}
},
_ => true,
}
Expand Down
11 changes: 10 additions & 1 deletion crates/uv-toolchain/src/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,8 @@ impl ExternallyManaged {
pub enum Error {
#[error("Failed to query Python interpreter")]
Io(#[from] io::Error),
#[error("Python interpreter not found at `{0}`")]
NotFound(PathBuf),
#[error("Failed to query Python interpreter at `{path}`")]
SpawnFailed {
path: PathBuf,
Expand Down Expand Up @@ -645,7 +647,14 @@ impl InterpreterInfo {

// We check the timestamp of the canonicalized executable to check if an underlying
// interpreter has been modified
let modified = Timestamp::from_path(uv_fs::canonicalize_executable(executable)?)?;
let modified =
Timestamp::from_path(uv_fs::canonicalize_executable(executable).map_err(|err| {
if err.kind() == io::ErrorKind::NotFound {
Error::NotFound(executable.to_path_buf())
} else {
err.into()
}
})?)?;

// Read from the cache.
if cache
Expand Down
40 changes: 13 additions & 27 deletions crates/uv/tests/pip_compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,33 +129,19 @@ fn missing_venv() -> Result<()> {
context.temp_dir.child("requirements.in").touch()?;
fs_err::remove_dir_all(context.temp_dir.child(".venv").path())?;

if cfg!(windows) {
uv_snapshot!(context.filters(), context.compile()
.arg("requirements.in"), @r###"
success: false
exit_code: 2
----- stdout -----
----- stderr -----
warning: Requirements file requirements.in does not contain any dependencies
error: failed to canonicalize path `[VENV]/Scripts/python.exe`
Caused by: The system cannot find the path specified. (os error 3)
"###
);
} else {
uv_snapshot!(context.filters(), context.compile()
.arg("requirements.in"), @r###"
success: false
exit_code: 2
----- stdout -----
----- stderr -----
warning: Requirements file requirements.in does not contain any dependencies
error: failed to canonicalize path `[VENV]/bin/python3`
Caused by: No such file or directory (os error 2)
"###
);
}
uv_snapshot!(context.filters(), context.compile()
.arg("requirements.in"), @r###"
success: true
exit_code: 0
----- stdout -----
# This file was autogenerated by uv via the following command:
# uv pip compile --cache-dir [CACHE_DIR] --exclude-newer 2024-03-25T00:00:00Z requirements.in
----- stderr -----
warning: Requirements file requirements.in does not contain any dependencies
Resolved 0 packages in [TIME]
"###
);

context
.temp_dir
Expand Down
29 changes: 8 additions & 21 deletions crates/uv/tests/pip_sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,27 +110,14 @@ fn missing_venv() -> Result<()> {
requirements.write_str("anyio")?;
fs::remove_dir_all(&context.venv)?;

if cfg!(windows) {
uv_snapshot!(context.filters(), sync_without_exclude_newer(&context).arg("requirements.txt"), @r###"
success: false
exit_code: 2
----- stdout -----
----- stderr -----
error: failed to canonicalize path `[VENV]/Scripts/python.exe`
Caused by: The system cannot find the path specified. (os error 3)
"###);
} else {
uv_snapshot!(context.filters(), sync_without_exclude_newer(&context).arg("requirements.txt"), @r###"
success: false
exit_code: 2
----- stdout -----
----- stderr -----
error: failed to canonicalize path `[VENV]/bin/python3`
Caused by: No such file or directory (os error 2)
"###);
}
uv_snapshot!(context.filters(), sync_without_exclude_newer(&context).arg("requirements.txt"), @r###"
success: false
exit_code: 2
----- stdout -----
----- stderr -----
error: No Python interpreters found in virtual environments
"###);

assert!(predicates::path::missing().eval(&context.venv));

Expand Down

0 comments on commit fa1a488

Please sign in to comment.