replace manual venv removal with remove_virtualenv (#15007)

<!--
Thank you for contributing to uv! To help us out with reviewing, please
consider the following:

- Does this pull request include a summary of the change? (See below.)
- Does this pull request include a descriptive title?
- Does this pull request include references to any relevant issues?
-->

## Summary

<!-- What's the purpose of the change? What does it do, and why? -->
At some places the virtualenv directory was manually removed instead of
using `remove_virtualenv`.
I also adjusted the error type.
#14985 

## Test Plan

<!-- How was it tested? -->
This commit is contained in:
Lars Grams 2025-08-07 22:52:57 +02:00 committed by GitHub
parent 7b1fb5b50b
commit d73edb019d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 14 additions and 19 deletions

1
Cargo.lock generated
View file

@ -5966,7 +5966,6 @@ version = "0.0.1"
dependencies = [ dependencies = [
"fs-err", "fs-err",
"pathdiff", "pathdiff",
"self-replace",
"serde", "serde",
"thiserror 2.0.12", "thiserror 2.0.12",
"toml", "toml",

View file

@ -39,6 +39,3 @@ thiserror = { workspace = true }
toml = { workspace = true } toml = { workspace = true }
toml_edit = { workspace = true } toml_edit = { workspace = true }
tracing = { workspace = true } tracing = { workspace = true }
[target.'cfg(target_os = "windows")'.dependencies]
self-replace = { workspace = true }

View file

@ -24,6 +24,7 @@ use uv_installer::SitePackages;
use uv_python::{Interpreter, PythonEnvironment}; use uv_python::{Interpreter, PythonEnvironment};
use uv_state::{StateBucket, StateStore}; use uv_state::{StateBucket, StateStore};
use uv_static::EnvVars; use uv_static::EnvVars;
use uv_virtualenv::remove_virtualenv;
mod receipt; mod receipt;
mod tool; mod tool;
@ -188,17 +189,7 @@ impl InstalledTools {
environment_path.user_display() environment_path.user_display()
); );
// On Windows, if the current executable is in the directory, guard against self-deletion. remove_virtualenv(environment_path.as_path())?;
#[cfg(windows)]
if let Ok(itself) = std::env::current_exe() {
let target = std::path::absolute(&environment_path)?;
if itself.starts_with(&target) {
debug!("Detected self-delete of executable: {}", itself.display());
self_replace::self_delete_outside_path(&environment_path)?;
}
}
fs_err::remove_dir_all(environment_path)?;
Ok(()) Ok(())
} }

View file

@ -1578,7 +1578,7 @@ impl ScriptEnvironment {
} }
// Remove the existing virtual environment. // Remove the existing virtual environment.
let replaced = match fs_err::remove_dir_all(&root) { let replaced = match remove_virtualenv(&root) {
Ok(()) => { Ok(()) => {
debug!( debug!(
"Removed virtual environment at: {}", "Removed virtual environment at: {}",
@ -1586,7 +1586,11 @@ impl ScriptEnvironment {
); );
true true
} }
Err(err) if err.kind() == std::io::ErrorKind::NotFound => false, Err(uv_virtualenv::Error::Io(err))
if err.kind() == std::io::ErrorKind::NotFound =>
{
false
}
Err(err) => return Err(err.into()), Err(err) => return Err(err.into()),
}; };

View file

@ -110,7 +110,9 @@ async fn do_uninstall(
)?; )?;
continue; continue;
} }
Err(uv_tool::Error::Io(err)) if err.kind() == std::io::ErrorKind::NotFound => { Err(uv_tool::Error::VirtualEnvError(uv_virtualenv::Error::Io(err)))
if err.kind() == std::io::ErrorKind::NotFound =>
{
bail!("`{name}` is not installed"); bail!("`{name}` is not installed");
} }
Err(err) => { Err(err) => {
@ -135,7 +137,9 @@ async fn do_uninstall(
)?; )?;
return Ok(()); return Ok(());
} }
Err(uv_tool::Error::Io(err)) if err.kind() == std::io::ErrorKind::NotFound => { Err(uv_tool::Error::VirtualEnvError(uv_virtualenv::Error::Io(err)))
if err.kind() == std::io::ErrorKind::NotFound =>
{
bail!("`{name}` is not installed"); bail!("`{name}` is not installed");
} }
Err(err) => { Err(err) => {