diff --git a/crates/uv/src/commands/pip/operations.rs b/crates/uv/src/commands/pip/operations.rs index 4e2bd312b549..c34b8e089a14 100644 --- a/crates/uv/src/commands/pip/operations.rs +++ b/crates/uv/src/commands/pip/operations.rs @@ -463,7 +463,15 @@ pub(crate) async fn install( install_wheel_rs::Error::MissingRecord(_), )) => { warn_user!( - "Failed to uninstall package at {} due to missing RECORD file. Installation may result in an incomplete environment.", + "Failed to uninstall package at {} due to missing `RECORD` file. Installation may result in an incomplete environment.", + dist_info.path().user_display().cyan(), + ); + } + Err(uv_installer::UninstallError::Uninstall( + install_wheel_rs::Error::MissingTopLevel(_), + )) => { + warn_user!( + "Failed to uninstall package at {} due to missing `top-level.txt` file. Installation may result in an incomplete environment.", dist_info.path().user_display().cyan(), ); } diff --git a/crates/uv/tests/pip_install.rs b/crates/uv/tests/pip_install.rs index 712c0d26fa4e..1307317c95d3 100644 --- a/crates/uv/tests/pip_install.rs +++ b/crates/uv/tests/pip_install.rs @@ -13,7 +13,9 @@ use url::Url; use common::{uv_snapshot, TestContext}; use uv_fs::Simplified; -use crate::common::{build_vendor_links_url, decode_token, get_bin, venv_bin_path}; +use crate::common::{ + build_vendor_links_url, decode_token, get_bin, venv_bin_path, venv_to_interpreter, +}; mod common; @@ -6455,3 +6457,40 @@ fn stale_egg_info() -> Result<()> { Ok(()) } + +/// `suds-community` has an incorrect layout whereby the wheel includes `suds_community.egg-info` at +/// the top-level. We're then under the impression that `suds` is installed twice, but when we go to +/// uninstall the second "version", we can't find the `egg-info` directory. +#[test] +fn missing_top_level() { + let context = TestContext::new("3.12"); + + uv_snapshot!(context.filters(), context.pip_install() + .arg("suds-community==0.8.5"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Resolved 1 package in [TIME] + Prepared 1 package in [TIME] + Installed 1 package in [TIME] + + suds-community==0.8.5 + "### + ); + + uv_snapshot!(context.filters(), context.pip_install() + .arg("suds-community==0.8.5"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Resolved 1 package in [TIME] + warning: Failed to uninstall package at [SITE_PACKAGES]/suds_community.egg-info due to missing `top-level.txt` file. Installation may result in an incomplete environment. + Uninstalled 2 packages in [TIME] + Installed 1 package in [TIME] + ~ suds-community==0.8.5 + "### + ); +}