From 024ac6e0627dda79e2edcf82d4588f04ec0820f4 Mon Sep 17 00:00:00 2001 From: John Mumm Date: Thu, 24 Apr 2025 14:51:27 +0200 Subject: [PATCH 1/2] Revert "Temporarily remove bogus redirect test (#13076)" This reverts commit a6a0087f748c25b2d94db26c5d87815c67b3991b. --- crates/uv/tests/it/pip_install.rs | 34 +++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/crates/uv/tests/it/pip_install.rs b/crates/uv/tests/it/pip_install.rs index 80d9a41c78b46..e4709c84dc2b3 100644 --- a/crates/uv/tests/it/pip_install.rs +++ b/crates/uv/tests/it/pip_install.rs @@ -11127,3 +11127,37 @@ fn pep_751_multiple_sources() -> Result<()> { Ok(()) } + +/// Test that uv doesn't hang if an index returns a distribution for the wrong package. +#[tokio::test] +async fn bogus_redirect() -> Result<()> { + let context = TestContext::new("3.12"); + + let redirect_server = MockServer::start().await; + + // Configure a bogus redirect where for all packages, anyio is returned. + Mock::given(method("GET")) + .respond_with( + ResponseTemplate::new(302).insert_header("Location", "https://pypi.org/simple/anyio/"), + ) + .mount(&redirect_server) + .await; + + uv_snapshot!( + context + .pip_install() + .arg("--default-index") + .arg(redirect_server.uri()) + .arg("sniffio"), + @r" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + error: The index returned metadata for the wrong package: expected distribution for sniffio, got distribution for anyio + " + ); + + Ok(()) +} From 43fbb5265d55aae59d3b8e619e7305fd2c443687 Mon Sep 17 00:00:00 2001 From: John Mumm Date: Thu, 24 Apr 2025 10:03:28 +0200 Subject: [PATCH 2/2] Debug bogus redirect hang --- crates/uv-distribution-types/src/lib.rs | 22 ++++++++++++++++++ crates/uv-resolver/src/resolver/mod.rs | 30 +++++++++++++++++++++---- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/crates/uv-distribution-types/src/lib.rs b/crates/uv-distribution-types/src/lib.rs index 1cb983be24ee9..2732d1fdb0123 100644 --- a/crates/uv-distribution-types/src/lib.rs +++ b/crates/uv-distribution-types/src/lib.rs @@ -844,6 +844,28 @@ impl Name for Dist { } } +impl Name for CompatibleDist<'_> { + fn name(&self) -> &PackageName { + match self { + CompatibleDist::InstalledDist(dist) => dist.name(), + CompatibleDist::SourceDist { + sdist, + prioritized: _, + } => sdist.name(), + CompatibleDist::CompatibleWheel { + wheel, + priority: _, + prioritized: _, + } => wheel.name(), + CompatibleDist::IncompatibleWheel { + sdist, + wheel: _, + prioritized: _, + } => sdist.name(), + } + } +} + impl DistributionMetadata for RegistryBuiltWheel { fn version_or_url(&self) -> VersionOrUrlRef { VersionOrUrlRef::Version(&self.filename.version) diff --git a/crates/uv-resolver/src/resolver/mod.rs b/crates/uv-resolver/src/resolver/mod.rs index 7ae2636bc0077..966b39005e78b 100644 --- a/crates/uv-resolver/src/resolver/mod.rs +++ b/crates/uv-resolver/src/resolver/mod.rs @@ -1320,7 +1320,7 @@ impl ResolverState ResolverState ResolverState>() .join(", ") ); - self.visit_candidate(candidate, dist, package, pins, request_sink)?; - self.visit_candidate(&base_candidate, base_dist, package, pins, request_sink)?; + self.visit_candidate(candidate, dist, package, name, pins, request_sink)?; + self.visit_candidate( + &base_candidate, + base_dist, + package, + name, + pins, + request_sink, + )?; let forks = vec![ VersionFork { @@ -1551,6 +1565,7 @@ impl ResolverState, ) -> Result<(), ResolveError> { @@ -1562,6 +1577,13 @@ impl ResolverState