Add markers to edges rather than distributions (#4166)

## Summary

We've debated this a bit but the thing that tipped me over the edge is
https://github.com/astral-sh/uv/issues/4157. As-is, there's no way to
represent "a package should be installed, but the extra should only be
installed conditionally based on the markers", because the markers sit
on the _distribution_. By placing the markers on the edge, we can now
represent scenarios that weren't previously representable.

Closes https://github.com/astral-sh/uv/issues/4137.
Closes https://github.com/astral-sh/uv/issues/4125.
Closes https://github.com/astral-sh/uv/issues/4157.
This commit is contained in:
Charlie Marsh 2024-06-10 05:40:51 -07:00 committed by GitHub
parent 5269a0dba8
commit 763e2d2e84
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 280 additions and 112 deletions

View file

@ -1566,12 +1566,14 @@ impl SolveState {
to_version: dependency_version.clone(),
to_extra: dependency_extra.clone(),
to_dev: dependency_dev.clone(),
marker: None,
};
dependencies.entry(names).or_default().insert(versions);
}
PubGrubPackageInner::Marker {
name: ref dependency_name,
marker: ref dependency_marker,
..
} => {
if self_name == dependency_name {
@ -1588,6 +1590,7 @@ impl SolveState {
to_version: dependency_version.clone(),
to_extra: None,
to_dev: None,
marker: Some(dependency_marker.clone()),
};
dependencies.entry(names).or_default().insert(versions);
}
@ -1595,6 +1598,7 @@ impl SolveState {
PubGrubPackageInner::Extra {
name: ref dependency_name,
extra: ref dependency_extra,
marker: ref dependency_marker,
..
} => {
if self_name == dependency_name {
@ -1611,6 +1615,7 @@ impl SolveState {
to_version: dependency_version.clone(),
to_extra: Some(dependency_extra.clone()),
to_dev: None,
marker: dependency_marker.clone(),
};
dependencies.entry(names).or_default().insert(versions);
}
@ -1618,6 +1623,7 @@ impl SolveState {
PubGrubPackageInner::Dev {
name: ref dependency_name,
dev: ref dependency_dev,
marker: ref dependency_marker,
..
} => {
if self_name == dependency_name {
@ -1634,6 +1640,7 @@ impl SolveState {
to_version: dependency_version.clone(),
to_extra: None,
to_dev: Some(dependency_dev.clone()),
marker: dependency_marker.clone(),
};
dependencies.entry(names).or_default().insert(versions);
}
@ -1676,6 +1683,7 @@ pub(crate) struct ResolutionDependencyVersions {
pub(crate) to_version: Version,
pub(crate) to_extra: Option<ExtraName>,
pub(crate) to_dev: Option<GroupName>,
pub(crate) marker: Option<MarkerTree>,
}
impl Resolution {