Skip to content

Commit

Permalink
progress
Browse files Browse the repository at this point in the history
  • Loading branch information
BurntSushi committed Apr 18, 2024
1 parent 2cf788f commit 7f2b401
Show file tree
Hide file tree
Showing 4 changed files with 192 additions and 64 deletions.
58 changes: 37 additions & 21 deletions crates/uv-resolver/src/pubgrub/dependencies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ impl PubGrubDependencies {
overrides: &Overrides,
source_name: Option<&PackageName>,
source_extra: Option<&ExtraName>,
source_marker: Option<MarkerTree>,
urls: &Urls,
locals: &Locals,
env: &MarkerEnvironment,
Expand All @@ -44,14 +45,27 @@ impl PubGrubDependencies {
}

// Add the package, plus any extra variants.
for result in std::iter::once(to_pubgrub(requirement, None, urls, locals)).chain(
requirement
.extras
.clone()
.into_iter()
.map(|extra| to_pubgrub(requirement, Some(extra), urls, locals)),
) {
let (mut package, version, marker) = result?;
let package = to_pubgrub(requirement, None, None, urls, locals);
let virtual_extras = requirement
.extras
.clone()
.into_iter()
.map(|extra| to_pubgrub(requirement, Some(extra), None, urls, locals));
let virtual_marker = requirement.marker.as_ref().map(|marker| {
// Uncomment the below to get marker stacking (albeit it is incorrect
// at time of writing).
// let mut m = source_marker
// .clone()
// .unwrap_or_else(|| MarkerTree::And(vec![]));
// m.and(marker.clone());
let m = marker.clone();
to_pubgrub(requirement, None, Some(m), urls, locals)
});
let it = std::iter::once(package)
.chain(virtual_extras)
.chain(virtual_marker);
for result in it {
let (mut package, version, _) = result?;

// Detect self-dependencies.
if let PubGrubPackage::Package { name, extra, .. } = &mut package {
Expand All @@ -64,7 +78,7 @@ impl PubGrubDependencies {
}
}

dependencies.push((package.clone(), version.clone(), marker));
dependencies.push((package.clone(), version.clone(), None));

// If the requirement was constrained, add those constraints.
for constraint in constraints.get(&requirement.name).into_iter().flatten() {
Expand All @@ -77,13 +91,13 @@ impl PubGrubDependencies {
}

// Add the package, plus any extra variants.
for result in std::iter::once(to_pubgrub(constraint, None, urls, locals)).chain(
constraint
.extras
.clone()
.into_iter()
.map(|extra| to_pubgrub(constraint, Some(extra), urls, locals)),
) {
for result in std::iter::once(to_pubgrub(constraint, None, None, urls, locals))
.chain(
constraint.extras.clone().into_iter().map(|extra| {
to_pubgrub(constraint, Some(extra), None, urls, locals)
}),
)
{
let (mut package, version, marker) = result?;

// Detect self-dependencies.
Expand Down Expand Up @@ -135,16 +149,17 @@ impl From<PubGrubDependencies> for Vec<(PubGrubPackage, Range<Version>, Option<M
fn to_pubgrub(
requirement: &Requirement,
extra: Option<ExtraName>,
marker: Option<MarkerTree>,
urls: &Urls,
locals: &Locals,
) -> Result<(PubGrubPackage, Range<Version>, Option<MarkerTree>), ResolveError> {
let marker = requirement.marker.clone();
// let marker = requirement.marker.clone();
match requirement.version_or_url.as_ref() {
// The requirement has no specifier (e.g., `flask`).
None => Ok((
PubGrubPackage::from_package(requirement.name.clone(), extra, urls),
PubGrubPackage::from_package(requirement.name.clone(), extra, marker, urls),
Range::full(),
marker,
None,
)),

// The requirement has a specifier (e.g., `flask>=1.0`).
Expand Down Expand Up @@ -172,9 +187,9 @@ fn to_pubgrub(
};

Ok((
PubGrubPackage::from_package(requirement.name.clone(), extra, urls),
PubGrubPackage::from_package(requirement.name.clone(), extra, marker, urls),
version,
marker,
None,
))
}

Expand All @@ -199,6 +214,7 @@ fn to_pubgrub(
PubGrubPackage::Package {
name: requirement.name.clone(),
extra,
marker: marker.clone(),
url: Some(expected.clone()),
},
Range::full(),
Expand Down
37 changes: 33 additions & 4 deletions crates/uv-resolver/src/pubgrub/package.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use derivative::Derivative;

use pep508_rs::VerbatimUrl;
use pep508_rs::{MarkerTree, VerbatimUrl};
use uv_normalize::{ExtraName, PackageName};

use crate::resolver::Urls;
Expand Down Expand Up @@ -50,6 +50,7 @@ pub enum PubGrubPackage {
Package {
name: PackageName,
extra: Option<ExtraName>,
marker: Option<MarkerTree>,
/// The URL of the package, if it was specified in the requirement.
///
/// There are a few challenges that come with URL-based packages, and how they map to
Expand Down Expand Up @@ -92,9 +93,19 @@ pub enum PubGrubPackage {

impl PubGrubPackage {
/// Create a [`PubGrubPackage`] from a package name and optional extra name.
pub(crate) fn from_package(name: PackageName, extra: Option<ExtraName>, urls: &Urls) -> Self {
pub(crate) fn from_package(
name: PackageName,
extra: Option<ExtraName>,
marker: Option<MarkerTree>,
urls: &Urls,
) -> Self {
let url = urls.get(&name).cloned();
Self::Package { name, extra, url }
Self::Package {
name,
extra,
marker,
url,
}
}

pub(crate) fn name(&self) -> &str {
Expand Down Expand Up @@ -127,15 +138,33 @@ impl std::fmt::Display for PubGrubPackage {
}
Self::Python(_) => write!(f, "Python"),
Self::Package {
name, extra: None, ..
name,
extra: None,
marker: None,
..
} => write!(f, "{name}"),
Self::Package {
name,
extra: None,
marker: Some(ref marker),
..
} => write!(f, "{name}{{{marker}}}"),
Self::Package {
name,
extra: Some(extra),
marker: None,
..
} => {
write!(f, "{name}[{extra}]")
}
Self::Package {
name,
extra: Some(extra),
marker: Some(ref marker),
..
} => {
write!(f, "{name}[{extra}]{{{marker}}}")
}
}
}
}
43 changes: 38 additions & 5 deletions crates/uv-resolver/src/resolution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ pub struct ResolutionGraph {
hashes: FxHashMap<PackageName, Vec<Hashes>>,
/// The enabled extras for every distribution in this resolution.
extras: FxHashMap<PackageName, Vec<ExtraName>>,
/// The markers tracked for a particular version of a package.
markers: FxHashMap<(PackageName, Version), MarkerTree>,
/// The set of editable requirements in this resolution.
editables: Editables,
/// Any diagnostics that were encountered while building the graph.
Expand Down Expand Up @@ -85,19 +87,34 @@ impl ResolutionGraph {
BuildHasherDefault::default(),
);
let mut extras = FxHashMap::default();
let mut markers = FxHashMap::default();
let mut diagnostics = Vec::new();

// Add every package to the graph.
let mut inverse = FxHashMap::with_capacity_and_hasher(
resolution.packages.len(),
BuildHasherDefault::default(),
);
// dbg!(&resolution.packages);
for (package, versions) in &resolution.packages {
for (version, markers) in versions {
for (version, _markers) in versions {
match package {
PubGrubPackage::Package {
name: package_name,
extra: None,
marker: Some(ref marker),
url: None,
} => {
let key = (package_name.clone(), version.clone());
markers
.entry(key)
.or_insert_with(|| MarkerTree::Or(vec![]))
.or(marker.clone());
}
PubGrubPackage::Package {
name: package_name,
extra: None,
marker: None,
url: None,
} => {
// Create the distribution.
Expand Down Expand Up @@ -129,13 +146,14 @@ impl ResolutionGraph {
// Add the distribution to the graph.
let index = petgraph.add_node(ResolvedNode {
dist: pinned_package,
markers: markers.clone(),
markers: None,
});
inverse.insert(package_name, index);
}
PubGrubPackage::Package {
name: package_name,
extra: None,
marker: None,
url: Some(url),
} => {
// Create the distribution.
Expand Down Expand Up @@ -167,13 +185,14 @@ impl ResolutionGraph {
// Add the distribution to the graph.
let index = petgraph.add_node(ResolvedNode {
dist: pinned_package.into(),
markers: markers.clone(),
markers: None,
});
inverse.insert(package_name, index);
}
PubGrubPackage::Package {
name: package_name,
extra: Some(extra),
marker: None,
url: None,
} => {
// Validate that the `extra` exists.
Expand Down Expand Up @@ -229,6 +248,7 @@ impl ResolutionGraph {
PubGrubPackage::Package {
name: package_name,
extra: Some(extra),
marker: None,
url: Some(url),
} => {
// Validate that the `extra` exists.
Expand Down Expand Up @@ -296,6 +316,7 @@ impl ResolutionGraph {
petgraph,
hashes,
extras,
markers,
editables,
diagnostics,
})
Expand Down Expand Up @@ -627,17 +648,29 @@ impl std::fmt::Display for DisplayResolutionGraph<'_> {
let node = if let Some((editable, _)) = self.resolution.editables.get(name) {
Node::Editable(name, editable)
} else if self.include_extras {
let version = match dist.version_or_url() {
VersionOrUrl::Version(v) => v.clone(),
_ => unreachable!(),
};
let key = (dist.name().clone(), version.clone());
let marker = self.resolution.markers.get(&key);
Node::Distribution(
name,
dist,
self.resolution
.extras
.get(name)
.map_or(&[], |extras| extras.as_slice()),
node.markers.as_ref(),
marker,
)
} else {
Node::Distribution(name, dist, &[], node.markers.as_ref())
let version = match dist.version_or_url() {
VersionOrUrl::Version(v) => v.clone(),
_ => unreachable!(),
};
let key = (dist.name().clone(), version.clone());
let marker = self.resolution.markers.get(&key);
Node::Distribution(name, dist, &[], marker)
};
Some((index, node))
})
Expand Down

0 comments on commit 7f2b401

Please sign in to comment.