Skip to content

Commit

Permalink
Collapse extras on dev dependencies (#6383)
Browse files Browse the repository at this point in the history
## Summary

It turns out we weren't applying the collapse logic here, so dev deps
with extras were repeated. This was generally ok... unless we ended up
_dropping_ an extra, in which case, you now have a duplicate.

Closes #6380.
  • Loading branch information
charliermarsh authored Aug 21, 2024
1 parent 7d90c29 commit 19a7f3e
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 15 deletions.
26 changes: 18 additions & 8 deletions crates/uv-resolver/src/lock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1154,10 +1154,15 @@ impl Package {
annotated_dist: &AnnotatedDist,
marker: MarkerTree,
) {
self.optional_dependencies
.entry(extra)
.or_default()
.push(Dependency::from_annotated_dist(annotated_dist, marker));
let dep = Dependency::from_annotated_dist(annotated_dist, marker);
let optional_deps = self.optional_dependencies.entry(extra).or_default();
for existing_dep in &mut *optional_deps {
if existing_dep.package_id == dep.package_id && existing_dep.marker == dep.marker {
existing_dep.extra.extend(dep.extra);
return;
}
}
optional_deps.push(dep);
}

/// Add the [`AnnotatedDist`] as a development dependency of the [`Package`].
Expand All @@ -1167,10 +1172,15 @@ impl Package {
annotated_dist: &AnnotatedDist,
marker: MarkerTree,
) {
self.dev_dependencies
.entry(dev)
.or_default()
.push(Dependency::from_annotated_dist(annotated_dist, marker));
let dep = Dependency::from_annotated_dist(annotated_dist, marker);
let dev_deps = self.dev_dependencies.entry(dev).or_default();
for existing_dep in &mut *dev_deps {
if existing_dep.package_id == dep.package_id && existing_dep.marker == dep.marker {
existing_dep.extra.extend(dep.extra);
return;
}
}
dev_deps.push(dep);
}

/// Convert the [`Package`] to a [`Dist`] that can be used in installation.
Expand Down
116 changes: 115 additions & 1 deletion crates/uv/tests/lock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7890,7 +7890,6 @@ fn lock_transitive_extra() -> Result<()> {
[package.optional-dependencies]
async = [
{ name = "leaf" },
{ name = "leaf", extra = ["async"] },
{ name = "typing-extensions" },
]
Expand Down Expand Up @@ -10306,3 +10305,118 @@ fn lock_virtual() -> Result<()> {

Ok(())
}

/// `coverage` defines a `toml` extra, but it doesn't enable any dependencies after Python 3.11.
#[test]
fn lock_dropped_dev_extra() -> Result<()> {
let context = TestContext::new("3.12");

let pyproject_toml = context.temp_dir.child("pyproject.toml");
pyproject_toml.write_str(
r#"
[project]
name = "project"
version = "0.1.0"
requires-python = ">=3.12"
[tool.uv]
dev-dependencies = [
"coverage[toml]"
]
"#,
)?;

uv_snapshot!(context.filters(), context.lock(), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Resolved 2 packages in [TIME]
"###);

let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap();

insta::with_settings!({
filters => context.filters(),
}, {
assert_snapshot!(
lock, @r###"
version = 1
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "coverage"
version = "7.4.4"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/bf/d5/f809d8b630cf4c11fe490e20037a343d12a74ec2783c6cdb5aee725e7137/coverage-7.4.4.tar.gz", hash = "sha256:c901df83d097649e257e803be22592aedfd5182f07b3cc87d640bbb9afd50f49", size = 783727 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/a0/de/a54b245e781bfd6f3fd7ce5566a695686b5c25ee7c743f514e7634428972/coverage-7.4.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:201bef2eea65e0e9c56343115ba3814e896afe6d36ffd37bab783261db430f76", size = 206409 },
{ url = "https://files.pythonhosted.org/packages/88/92/07f9c593cd27e3c595b8cb83b95adad8c9ba3d611debceed097a5fd6be4b/coverage-7.4.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:41c9c5f3de16b903b610d09650e5e27adbfa7f500302718c9ffd1c12cf9d6818", size = 206568 },
{ url = "https://files.pythonhosted.org/packages/41/6d/e142c823e5d4b24481f990da4cf9d2d577a6f4e1fb6faf39d9a4e42b1d43/coverage-7.4.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d898fe162d26929b5960e4e138651f7427048e72c853607f2b200909794ed978", size = 238920 },
{ url = "https://files.pythonhosted.org/packages/30/1a/105f0139df6a2adbcaa0c110711a46dbd9f59e93a09ca15a97d59c2564f2/coverage-7.4.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3ea79bb50e805cd6ac058dfa3b5c8f6c040cb87fe83de10845857f5535d1db70", size = 236288 },
{ url = "https://files.pythonhosted.org/packages/98/79/185cb42910b6a2b2851980407c8445ac0da0750dff65e420e86f973c8396/coverage-7.4.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce4b94265ca988c3f8e479e741693d143026632672e3ff924f25fab50518dd51", size = 238223 },
{ url = "https://files.pythonhosted.org/packages/92/12/2303d1c543a11ea060dbc7144ed3174fc09107b5dd333649415c95ede58b/coverage-7.4.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:00838a35b882694afda09f85e469c96367daa3f3f2b097d846a7216993d37f4c", size = 245161 },
{ url = "https://files.pythonhosted.org/packages/96/5a/7d0e945c4759fe9d19aad1679dd3096aeb4cb9fcf0062fe24554dc4787b8/coverage-7.4.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:fdfafb32984684eb03c2d83e1e51f64f0906b11e64482df3c5db936ce3839d48", size = 243066 },
{ url = "https://files.pythonhosted.org/packages/f4/1b/79cdb7b11bbbd6540a536ac79412904b5c1f8903d5c1330084212afa8ceb/coverage-7.4.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:69eb372f7e2ece89f14751fbcbe470295d73ed41ecd37ca36ed2eb47512a6ab9", size = 244805 },
{ url = "https://files.pythonhosted.org/packages/af/7f/54dc676e7e63549838a3a7b95a8e11df80441bf7d64c6ce8f1cdbc0d1ff0/coverage-7.4.4-cp312-cp312-win32.whl", hash = "sha256:137eb07173141545e07403cca94ab625cc1cc6bc4c1e97b6e3846270e7e1fea0", size = 208590 },
{ url = "https://files.pythonhosted.org/packages/46/c4/1dfe76d96034a347d717a2392b004d42d45934cb94efa362ad41ca871f6e/coverage-7.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:d71eec7d83298f1af3326ce0ff1d0ea83c7cb98f72b577097f9083b20bdaf05e", size = 209415 },
]
[[package]]
name = "project"
version = "0.1.0"
source = { editable = "." }
[package.dev-dependencies]
dev = [
{ name = "coverage" },
]
[package.metadata]
[package.metadata.requires-dev]
dev = [{ name = "coverage", extras = ["toml"] }]
"###
);
});

// Re-run with `--locked`.
uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Resolved 2 packages in [TIME]
"###);

// Re-run with `--offline`. We shouldn't need a network connection to validate an
// already-correct lockfile with immutable metadata.
uv_snapshot!(context.filters(), context.lock().arg("--locked").arg("--offline").arg("--no-cache"), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Resolved 2 packages in [TIME]
"###);

// Install from the lockfile.
uv_snapshot!(context.filters(), context.sync().arg("--frozen"), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Prepared 2 packages in [TIME]
Installed 2 packages in [TIME]
+ coverage==7.4.4
+ project==0.1.0 (from file://[TEMP_DIR]/)
"###);

Ok(())
}
Original file line number Diff line number Diff line change
Expand Up @@ -5443,7 +5443,6 @@ all = [
{ name = "pillow" },
{ name = "protobuf" },
{ name = "pyctcdecode" },
{ name = "ray" },
{ name = "ray", extra = ["tune"] },
{ name = "sentencepiece" },
{ name = "sigopt" },
Expand Down Expand Up @@ -5542,7 +5541,6 @@ dev-dependencies = [
{ name = "pytest" },
{ name = "pytest-timeout" },
{ name = "pytest-xdist" },
{ name = "ray" },
{ name = "ray", extra = ["tune"] },
{ name = "rhoknp" },
{ name = "rjieba" },
Expand Down Expand Up @@ -5592,7 +5590,6 @@ docs = [
{ name = "pillow" },
{ name = "protobuf" },
{ name = "pyctcdecode" },
{ name = "ray" },
{ name = "ray", extra = ["tune"] },
{ name = "sentencepiece" },
{ name = "sigopt" },
Expand Down Expand Up @@ -5628,7 +5625,6 @@ ftfy = [
]
integrations = [
{ name = "optuna" },
{ name = "ray" },
{ name = "ray", extra = ["tune"] },
{ name = "sigopt" },
]
Expand Down Expand Up @@ -5668,7 +5664,6 @@ quality = [
{ name = "urllib3" },
]
ray = [
{ name = "ray" },
{ name = "ray", extra = ["tune"] },
]
retrieval = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,6 @@ wheels = [
[package.optional-dependencies]
sqs = [
{ name = "boto3" },
{ name = "kombu" },
{ name = "kombu", extra = ["sqs"] },
{ name = "pycurl", marker = "platform_python_implementation == 'CPython' and sys_platform != 'win32'" },
{ name = "urllib3" },
Expand Down

0 comments on commit 19a7f3e

Please sign in to comment.