From 801fd0e5b84121cfb75cc2636ac28916f6621a3c Mon Sep 17 00:00:00 2001 From: Christopher Tee Date: Fri, 2 May 2025 04:29:07 -0400 Subject: [PATCH] Deduplicate fetched index URLs (#13205) ## Summary Fixes #11970. ## Test Plan Ran `cargo nextest` --- crates/uv-distribution-types/src/index_url.rs | 2 + crates/uv/tests/it/pip_install.rs | 37 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/crates/uv-distribution-types/src/index_url.rs b/crates/uv-distribution-types/src/index_url.rs index e7f50cd18..4dc7d1b6e 100644 --- a/crates/uv-distribution-types/src/index_url.rs +++ b/crates/uv-distribution-types/src/index_url.rs @@ -489,9 +489,11 @@ impl<'a> IndexUrls { /// If `no_index` was enabled, then this always returns an empty /// iterator. pub fn indexes(&'a self) -> impl Iterator + 'a { + let mut seen = FxHashSet::default(); self.implicit_indexes() .chain(self.default_index()) .filter(|index| !index.explicit) + .filter(move |index| seen.insert(index.raw_url())) // Filter out redundant raw URLs } /// Return an iterator over all user-defined [`Index`] entries in order. diff --git a/crates/uv/tests/it/pip_install.rs b/crates/uv/tests/it/pip_install.rs index 88f2088f3..a3868a58e 100644 --- a/crates/uv/tests/it/pip_install.rs +++ b/crates/uv/tests/it/pip_install.rs @@ -1878,6 +1878,43 @@ fn install_extra_index_url_has_priority() { context.assert_command("import flask").failure(); } +/// Ensure that the index is fetched only once when duplicate indices are specified +#[tokio::test] +async fn install_deduplicated_indices() { + let context = TestContext::new("3.12"); + + let redirect_server = MockServer::start().await; + + Mock::given(method("GET")) + .respond_with( + ResponseTemplate::new(302).insert_header("Location", "https://pypi.org/simple/sniffio"), + ) + .expect(1) + .mount(&redirect_server) + .await; + + uv_snapshot!(context + .pip_install() + .arg("sniffio") // Use a zero-dependency package + .arg("--index") + .arg(redirect_server.uri()) + .arg("--default-index") + .arg(redirect_server.uri()) + .arg("--index-strategy") + .arg("unsafe-first-match"), // Anything but "first-index" + @r" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Resolved 1 package in [TIME] + Prepared 1 package in [TIME] + Installed 1 package in [TIME] + + sniffio==1.3.1 + "); +} + /// Install a package from a public GitHub repository #[test] #[cfg(feature = "git")]