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 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(()) +}