From 962fde29b2abb5d27d8d3d53f9201fcbcf2d212f Mon Sep 17 00:00:00 2001 From: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Date: Wed, 8 May 2024 01:40:21 -0700 Subject: [PATCH] Apply normcase to line from easy-install.pth (#3451) Thanks for the suggestion from https://github.com/astral-sh/uv/pull/3415#discussion_r1591772942 Also it looks like you improved `egg-link` parsing in https://github.com/astral-sh/uv/pull/3415/commits/e23c91f52e7df1a5230fc3cb7ca6d3d4ca0b24a2 so copying the changes over to the other parse site (happy to move this to a helper too, if so lmk where to put it) --- crates/distribution-types/src/installed.rs | 11 ++++++++--- crates/install-wheel-rs/src/uninstall.rs | 11 +++++++++++ crates/uv/tests/pip_uninstall.rs | 10 +++++++++- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/crates/distribution-types/src/installed.rs b/crates/distribution-types/src/installed.rs index 2eb382534..6fd08d2ef 100644 --- a/crates/distribution-types/src/installed.rs +++ b/crates/distribution-types/src/installed.rs @@ -142,9 +142,14 @@ impl InstalledDist { // https://setuptools.pypa.io/en/latest/deprecated/python_eggs.html#egg-links // https://github.com/pypa/pip/blob/946f95d17431f645da8e2e0bf4054a72db5be766/src/pip/_internal/metadata/importlib/_envs.py#L86-L108 let contents = fs::read_to_string(path)?; - let target = if let Some(line) = contents.lines().find(|line| !line.is_empty()) { - PathBuf::from(line.trim()) - } else { + let Some(target) = contents.lines().find_map(|line| { + let line = line.trim(); + if line.is_empty() { + None + } else { + Some(PathBuf::from(line)) + } + }) else { warn!("Invalid `.egg-link` file: {path:?}"); return Ok(None); }; diff --git a/crates/install-wheel-rs/src/uninstall.rs b/crates/install-wheel-rs/src/uninstall.rs index 760ee6a3a..35bc54869 100644 --- a/crates/install-wheel-rs/src/uninstall.rs +++ b/crates/install-wheel-rs/src/uninstall.rs @@ -211,6 +211,14 @@ pub fn uninstall_egg(egg_info: &Path) -> Result { }) } +fn normcase(s: &str) -> String { + if cfg!(windows) { + s.replace('/', "\\").to_lowercase() + } else { + s.to_owned() + } +} + static EASY_INSTALL_PTH: Lazy> = Lazy::new(Mutex::default); /// Uninstall the legacy editable represented by the `.egg-link` file. @@ -233,6 +241,9 @@ pub fn uninstall_legacy_editable(egg_link: &Path) -> Result { }) .ok_or_else(|| Error::InvalidEggLink(egg_link.to_path_buf()))?; + // This comes from `pkg_resources.normalize_path` + let target_line = normcase(target_line); + match fs::remove_file(egg_link) { Ok(()) => { debug!("Removed file: {}", egg_link.display()); diff --git a/crates/uv/tests/pip_uninstall.rs b/crates/uv/tests/pip_uninstall.rs index d3ceca9fe..f46af9b3f 100644 --- a/crates/uv/tests/pip_uninstall.rs +++ b/crates/uv/tests/pip_uninstall.rs @@ -474,6 +474,14 @@ fn uninstall_egg_info() -> Result<()> { Ok(()) } +fn normcase(s: &str) -> String { + if cfg!(windows) { + s.replace('/', "\\").to_lowercase() + } else { + s.to_owned() + } +} + /// Uninstall a legacy editable package in a virtual environment. #[test] fn uninstall_legacy_editable() -> Result<()> { @@ -502,7 +510,7 @@ Version: 0.22.0 site_packages.child("easy-install.pth").write_str(&format!( "something\n{}\nanother thing\n", - target.path().to_str().unwrap() + normcase(target.path().to_str().unwrap()) ))?; // Run `pip uninstall`.