diff --git a/crates/uv-python/src/downloads.rs b/crates/uv-python/src/downloads.rs index 4e865375da52..4e3e3f317f6a 100644 --- a/crates/uv-python/src/downloads.rs +++ b/crates/uv-python/src/downloads.rs @@ -465,13 +465,14 @@ impl ManagedPythonDownload { client: &uv_client::BaseClient, installation_dir: &Path, cache_dir: &Path, + reinstall: bool, reporter: Option<&dyn Reporter>, ) -> Result { let url = self.download_url()?; let path = installation_dir.join(self.key().to_string()); - // If it already exists, return it - if path.is_dir() { + // If it is not a reinstall and the dir already exists, return it. + if !reinstall && path.is_dir() { return Ok(DownloadResult::AlreadyAvailable(path)); } @@ -560,7 +561,13 @@ impl ManagedPythonDownload { } } - // Persist it to the target + // Remove the target if it already exists. + if path.is_dir() { + debug!("Removing existing directory: {}", path.user_display()); + fs_err::tokio::remove_dir_all(&path).await?; + } + + // Persist it to the target. debug!("Moving {} to {}", extracted.display(), path.user_display()); rename_with_retry(extracted, &path) .await diff --git a/crates/uv-python/src/installation.rs b/crates/uv-python/src/installation.rs index b0a326bad96c..c6bf4e81669e 100644 --- a/crates/uv-python/src/installation.rs +++ b/crates/uv-python/src/installation.rs @@ -132,7 +132,7 @@ impl PythonInstallation { info!("Fetching requested Python..."); let result = download - .fetch(&client, installations_dir, &cache_dir, reporter) + .fetch(&client, installations_dir, &cache_dir, false, reporter) .await?; let path = match result { diff --git a/crates/uv/src/commands/python/install.rs b/crates/uv/src/commands/python/install.rs index 601694359783..bb7c4be0b54c 100644 --- a/crates/uv/src/commands/python/install.rs +++ b/crates/uv/src/commands/python/install.rs @@ -1,5 +1,4 @@ use anyhow::Result; -use fs_err as fs; use futures::stream::FuturesUnordered; use futures::StreamExt; use itertools::Itertools; @@ -90,7 +89,6 @@ pub(crate) async fn install( )?; } if reinstall { - fs::remove_dir_all(installation.path())?; uninstalled.push(installation.key().clone()); unfilled_requests.push(download_request); } @@ -145,7 +143,13 @@ pub(crate) async fn install( ( download.key(), download - .fetch(&client, installations_dir, &cache_dir, Some(&reporter)) + .fetch( + &client, + installations_dir, + &cache_dir, + reinstall, + Some(&reporter), + ) .await, ) });