Skip to content

Commit

Permalink
Replace PubGrubDependencies by PubGrubDependency (#4481)
Browse files Browse the repository at this point in the history
In the last PR (#4430), we flatten the requirements. In the next PR
(#4435), we want to pass `Url` around next to `PubGrubPackage` and
`Range<Version>` to keep track of which `Requirement`s added a url
across forking. This PR is a refactoring split out from #4435 that rolls
the dependency conversion into a single iterator and introduces a new
`PubGrubDependency` struct as abstraction over `(PubGrubPackage,
Range<Version>)` (or `(PubGrubPackage, Range<Version>,
VerbatimParsedUrl)` in the next PR), and it removes the now unnecessary
`PubGrubDependencies` abstraction.
  • Loading branch information
konstin authored Jun 25, 2024
1 parent e6103dc commit ff2f927
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 121 deletions.
89 changes: 36 additions & 53 deletions crates/uv-resolver/src/pubgrub/dependencies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,76 +15,59 @@ use crate::pubgrub::{PubGrubPackage, PubGrubPackageInner};
use crate::resolver::{Locals, Urls};
use crate::{PubGrubSpecifier, ResolveError};

#[derive(Debug)]
pub struct PubGrubDependencies(Vec<(PubGrubPackage, Range<Version>)>);
#[derive(Clone, Debug)]
pub(crate) struct PubGrubDependency {
pub(crate) package: PubGrubPackage,
pub(crate) version: Range<Version>,
}

impl PubGrubDependencies {
/// Generate a set of PubGrub dependencies from a set of requirements.
#[allow(clippy::too_many_arguments)]
pub(crate) fn from_requirements(
flattened_requirements: &[&Requirement],
source_name: Option<&PackageName>,
urls: &Urls,
locals: &Locals,
git: &GitResolver,
) -> Result<Self, ResolveError> {
let mut dependencies = Vec::new();
for requirement in flattened_requirements {
// Add the package, plus any extra variants.
for result in std::iter::once(PubGrubRequirement::from_requirement(
requirement,
None,
urls,
locals,
git,
))
.chain(requirement.extras.clone().into_iter().map(|extra| {
PubGrubRequirement::from_requirement(requirement, Some(extra), urls, locals, git)
})) {
let PubGrubRequirement { package, version } = result?;
impl PubGrubDependency {
pub(crate) fn from_requirement<'a>(
requirement: &'a Requirement,
source_name: Option<&'a PackageName>,
urls: &'a Urls,
locals: &'a Locals,
git: &'a GitResolver,
) -> impl Iterator<Item = Result<Self, ResolveError>> + 'a {
// Add the package, plus any extra variants.
std::iter::once(None)
.chain(requirement.extras.clone().into_iter().map(Some))
.map(|extra| {
PubGrubRequirement::from_requirement(requirement, extra, urls, locals, git)
})
.filter_map_ok(move |pubgrub_requirement| {
let PubGrubRequirement { package, version } = pubgrub_requirement;

match &*package {
PubGrubPackageInner::Package { name, .. } => {
// Detect self-dependencies.
if source_name.is_some_and(|source_name| source_name == name) {
warn!("{name} has a dependency on itself");
continue;
return None;
}

dependencies.push((package.clone(), version.clone()));
}
PubGrubPackageInner::Marker { .. } => {
dependencies.push((package.clone(), version.clone()));
Some(PubGrubDependency {
package: package.clone(),
version: version.clone(),
})
}
PubGrubPackageInner::Marker { .. } => Some(PubGrubDependency {
package: package.clone(),
version: version.clone(),
}),
PubGrubPackageInner::Extra { name, .. } => {
debug_assert!(
!source_name.is_some_and(|source_name| source_name == name),
"extras not flattened for {name}"
);
dependencies.push((package.clone(), version.clone()));
Some(PubGrubDependency {
package: package.clone(),
version: version.clone(),
})
}
_ => {}
_ => None,
}
}
}
Ok(Self(dependencies))
}

/// Add a [`PubGrubPackage`] and [`PubGrubVersion`] range into the dependencies.
pub(crate) fn push(&mut self, package: PubGrubPackage, version: Range<Version>) {
self.0.push((package, version));
}

/// Iterate over the dependencies.
pub(crate) fn iter(&self) -> impl Iterator<Item = &(PubGrubPackage, Range<Version>)> {
self.0.iter()
}
}

/// Convert a [`PubGrubDependencies`] to a [`DependencyConstraints`].
impl From<PubGrubDependencies> for Vec<(PubGrubPackage, Range<Version>)> {
fn from(dependencies: PubGrubDependencies) -> Self {
dependencies.0
})
}
}

Expand Down
2 changes: 1 addition & 1 deletion crates/uv-resolver/src/pubgrub/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pub(crate) use crate::pubgrub::dependencies::PubGrubDependencies;
pub(crate) use crate::pubgrub::dependencies::PubGrubDependency;
pub(crate) use crate::pubgrub::distribution::PubGrubDistribution;
pub(crate) use crate::pubgrub::package::{PubGrubPackage, PubGrubPackageInner, PubGrubPython};
pub(crate) use crate::pubgrub::priority::{PubGrubPriorities, PubGrubPriority};
Expand Down
Loading

0 comments on commit ff2f927

Please sign in to comment.