Unify dependency iteration in ResolverState::get_dependencies (#4515)

Upstack PR: #4430

Split out from #4430 according to
https://github.com/astral-sh/uv/pull/4430#discussion_r1650192338.
This commit is contained in:
konsti 2024-06-25 23:04:49 +02:00 committed by GitHub
parent 5732209be3
commit ad42206e50
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 80 additions and 99 deletions

View file

@ -40,8 +40,6 @@ pub(crate) enum UnavailableVersion {
InvalidStructure, InvalidStructure,
/// The wheel metadata was not found in the cache and the network is not available. /// The wheel metadata was not found in the cache and the network is not available.
Offline, Offline,
/// Forward any kind of resolver error.
ResolverError(String),
} }
impl Display for UnavailableVersion { impl Display for UnavailableVersion {
@ -57,7 +55,6 @@ impl Display for UnavailableVersion {
UnavailableVersion::Offline => f.write_str( UnavailableVersion::Offline => f.write_str(
"network connectivity is disabled, but the metadata wasn't found in the cache", "network connectivity is disabled, but the metadata wasn't found in the cache",
), ),
UnavailableVersion::ResolverError(err) => f.write_str(err),
} }
} }
} }

View file

@ -936,7 +936,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
priorities: &mut PubGrubPriorities, priorities: &mut PubGrubPriorities,
request_sink: &Sender<Request>, request_sink: &Sender<Request>,
) -> Result<Dependencies, ResolveError> { ) -> Result<Dependencies, ResolveError> {
match &**package { let (dependencies, name) = match &**package {
PubGrubPackageInner::Root(_) => { PubGrubPackageInner::Root(_) => {
// Add the root requirements. // Add the root requirements.
let dependencies = PubGrubDependencies::from_requirements( let dependencies = PubGrubDependencies::from_requirements(
@ -953,31 +953,11 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
self.markers.as_ref(), self.markers.as_ref(),
self.requires_python.as_ref(), self.requires_python.as_ref(),
markers, markers,
); )?;
(dependencies, None)
let dependencies = match dependencies {
Ok(dependencies) => dependencies,
Err(err) => {
return Ok(Dependencies::Unavailable(
UnavailableVersion::ResolverError(uncapitalize(err.to_string())),
));
}
};
for (package, version) in dependencies.iter() {
debug!("Adding direct dependency: {package}{version}");
// Update the package priorities.
priorities.insert(package, version);
// Emit a request to fetch the metadata for this package.
self.visit_package(package, request_sink)?;
}
Ok(Dependencies::Available(dependencies.into()))
} }
PubGrubPackageInner::Python(_) => Ok(Dependencies::Available(Vec::default())), PubGrubPackageInner::Python(_) => return Ok(Dependencies::Available(Vec::default())),
PubGrubPackageInner::Package { PubGrubPackageInner::Package {
name, name,
@ -1108,16 +1088,6 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
markers, markers,
)?; )?;
for (dep_package, dep_version) in dependencies.iter() {
debug!("Adding transitive dependency for {package}=={version}: {dep_package}{dep_version}");
// Update the package priorities.
priorities.insert(dep_package, dep_version);
// Emit a request to fetch the metadata for this package.
self.visit_package(dep_package, request_sink)?;
}
// If a package has metadata for an enabled dependency group, // If a package has metadata for an enabled dependency group,
// add a dependency from it to the same package with the group // add a dependency from it to the same package with the group
// enabled. // enabled.
@ -1137,44 +1107,19 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
} }
} }
Ok(Dependencies::Available(dependencies.into())) (dependencies, Some(name))
} }
// Add a dependency on both the marker and base package. // Add a dependency on both the marker and base package.
PubGrubPackageInner::Marker { name, marker, url } => Ok(Dependencies::Available( PubGrubPackageInner::Marker { name, marker, url } => {
[None, Some(marker)] return Ok(Dependencies::Available(
.into_iter() [None, Some(marker)]
.map(move |marker| { .into_iter()
( .map(move |marker| {
PubGrubPackage::from(PubGrubPackageInner::Package {
name: name.clone(),
extra: None,
dev: None,
marker: marker.cloned(),
url: url.clone(),
}),
Range::singleton(version.clone()),
)
})
.collect(),
)),
// Add a dependency on both the extra and base package, with and without the marker.
PubGrubPackageInner::Extra {
name,
extra,
marker,
url,
} => Ok(Dependencies::Available(
[None, marker.as_ref()]
.into_iter()
.dedup()
.flat_map(move |marker| {
[None, Some(extra)].into_iter().map(move |extra| {
( (
PubGrubPackage::from(PubGrubPackageInner::Package { PubGrubPackage::from(PubGrubPackageInner::Package {
name: name.clone(), name: name.clone(),
extra: extra.cloned(), extra: None,
dev: None, dev: None,
marker: marker.cloned(), marker: marker.cloned(),
url: url.clone(), url: url.clone(),
@ -1182,9 +1127,38 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
Range::singleton(version.clone()), Range::singleton(version.clone()),
) )
}) })
}) .collect(),
.collect(), ))
)), }
// Add a dependency on both the extra and base package, with and without the marker.
PubGrubPackageInner::Extra {
name,
extra,
marker,
url,
} => {
return Ok(Dependencies::Available(
[None, marker.as_ref()]
.into_iter()
.dedup()
.flat_map(move |marker| {
[None, Some(extra)].into_iter().map(move |extra| {
(
PubGrubPackage::from(PubGrubPackageInner::Package {
name: name.clone(),
extra: extra.cloned(),
dev: None,
marker: marker.cloned(),
url: url.clone(),
}),
Range::singleton(version.clone()),
)
})
})
.collect(),
))
}
// Add a dependency on both the development dependency group and base package, with and // Add a dependency on both the development dependency group and base package, with and
// without the marker. // without the marker.
@ -1193,27 +1167,45 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
dev, dev,
marker, marker,
url, url,
} => Ok(Dependencies::Available( } => {
[None, marker.as_ref()] return Ok(Dependencies::Available(
.into_iter() [None, marker.as_ref()]
.dedup() .into_iter()
.flat_map(move |marker| { .dedup()
[None, Some(dev)].into_iter().map(move |dev| { .flat_map(move |marker| {
( [None, Some(dev)].into_iter().map(move |dev| {
PubGrubPackage::from(PubGrubPackageInner::Package { (
name: name.clone(), PubGrubPackage::from(PubGrubPackageInner::Package {
extra: None, name: name.clone(),
dev: dev.cloned(), extra: None,
marker: marker.cloned(), dev: dev.cloned(),
url: url.clone(), marker: marker.cloned(),
}), url: url.clone(),
Range::singleton(version.clone()), }),
) Range::singleton(version.clone()),
)
})
}) })
}) .collect(),
.collect(), ))
)), }
};
for (dep_package, dep_version) in dependencies.iter() {
if let Some(name) = name {
debug!("Adding transitive dependency for {name}=={version}: {dep_package}{dep_version}");
} else {
debug!("Adding direct dependency: {dep_package}{dep_version}");
}
// Update the package priorities.
priorities.insert(dep_package, dep_version);
// Emit a request to fetch the metadata for this package.
self.visit_package(dep_package, request_sink)?;
} }
Ok(Dependencies::Available(dependencies.into()))
} }
/// Fetch the metadata for a stream of packages and versions. /// Fetch the metadata for a stream of packages and versions.
@ -2298,11 +2290,3 @@ impl<'a> PossibleFork<'a> {
false false
} }
} }
fn uncapitalize<T: AsRef<str>>(string: T) -> String {
let mut chars = string.as_ref().chars();
match chars.next() {
None => String::new(),
Some(first) => first.to_lowercase().chain(chars).collect(),
}
}