Skip to content

Commit

Permalink
Allow duplicate URLs that resolve to the same canonical URL (#1877)
Browse files Browse the repository at this point in the history
Closes #1865.

Closes #1866.
  • Loading branch information
charliermarsh authored Feb 22, 2024
1 parent 12a96ad commit 6afbb02
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 15 deletions.
42 changes: 27 additions & 15 deletions crates/uv-resolver/src/resolver/urls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,15 @@ impl Urls {

if let Some(pep508_rs::VersionOrUrl::Url(url)) = &requirement.version_or_url {
if let Some(previous) = urls.insert(requirement.name.clone(), url.clone()) {
return Err(ResolveError::ConflictingUrlsDirect(
requirement.name.clone(),
previous.verbatim().to_string(),
url.verbatim().to_string(),
));
if cache_key::CanonicalUrl::new(previous.raw())
!= cache_key::CanonicalUrl::new(url.raw())
{
return Err(ResolveError::ConflictingUrlsDirect(
requirement.name.clone(),
previous.verbatim().to_string(),
url.verbatim().to_string(),
));
}
}
}
}
Expand All @@ -42,21 +46,29 @@ impl Urls {
if let Some(previous) =
urls.insert(metadata.name.clone(), editable_requirement.url.clone())
{
return Err(ResolveError::ConflictingUrlsDirect(
metadata.name.clone(),
previous.verbatim().to_string(),
editable_requirement.url.verbatim().to_string(),
));
if cache_key::CanonicalUrl::new(previous.raw())
!= cache_key::CanonicalUrl::new(editable_requirement.raw())
{
return Err(ResolveError::ConflictingUrlsDirect(
metadata.name.clone(),
previous.verbatim().to_string(),
editable_requirement.url.verbatim().to_string(),
));
}
}

for req in &metadata.requires_dist {
if let Some(pep508_rs::VersionOrUrl::Url(url)) = &req.version_or_url {
if let Some(previous) = urls.insert(req.name.clone(), url.clone()) {
return Err(ResolveError::ConflictingUrlsDirect(
req.name.clone(),
previous.verbatim().to_string(),
url.verbatim().to_string(),
));
if cache_key::CanonicalUrl::new(previous.raw())
!= cache_key::CanonicalUrl::new(url.raw())
{
return Err(ResolveError::ConflictingUrlsDirect(
req.name.clone(),
previous.verbatim().to_string(),
url.verbatim().to_string(),
));
}
}
}
}
Expand Down
24 changes: 24 additions & 0 deletions crates/uv/tests/pip_compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1363,6 +1363,30 @@ fn conflicting_transitive_url_dependency() -> Result<()> {
Ok(())
}

/// Request Werkzeug via two different URLs which resolve to the same canonical version.
#[test]
fn compatible_repeated_url_dependency() -> Result<()> {
let context = TestContext::new("3.12");
let requirements_in = context.temp_dir.child("requirements.in");
requirements_in.write_str("werkzeug @ git+https://github.com/pallets/[email protected]\nwerkzeug @ git+https://github.com/pallets/[email protected]")?;

uv_snapshot!(context.compile()
.arg("requirements.in"), @r###"
success: true
exit_code: 0
----- stdout -----
# This file was autogenerated by uv via the following command:
# uv pip compile --cache-dir [CACHE_DIR] --exclude-newer 2023-11-18T12:00:00Z requirements.in
werkzeug @ git+https://github.com/pallets/werkzeug@af160e0b6b7ddd81c22f1652c728ff5ac72d5c74
----- stderr -----
Resolved 1 package in [TIME]
"###
);

Ok(())
}

/// Request `transitive_url_dependency`, which depends on `git+https://github.com/pallets/[email protected]`.
/// Since this URL isn't declared upfront, we should reject it.
#[test]
Expand Down

0 comments on commit 6afbb02

Please sign in to comment.