Skip to content

Commit

Permalink
Avoid unnecessary progress bar initializations (#7412)
Browse files Browse the repository at this point in the history
## Summary

Closes #6343.
  • Loading branch information
charliermarsh authored Sep 15, 2024
1 parent 1986845 commit aa71c89
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 49 deletions.
17 changes: 7 additions & 10 deletions crates/uv-requirements/src/unnamed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use url::Host;
use distribution_filename::{DistExtension, SourceDistFilename, WheelFilename};
use distribution_types::{
BuildableSource, DirectSourceUrl, DirectorySourceUrl, GitSourceUrl, PathSourceUrl,
RemoteSource, SourceUrl, UnresolvedRequirement, UnresolvedRequirementSpecification, VersionId,
RemoteSource, SourceUrl, VersionId,
};
use pep508_rs::{UnnamedRequirement, VersionOrUrl};
use pypi_types::Requirement;
Expand All @@ -37,7 +37,7 @@ pub enum NamedRequirementsError {
/// Like [`RequirementsSpecification`], but with concrete names for all requirements.
pub struct NamedRequirementsResolver<'a, Context: BuildContext> {
/// The requirements for the project.
requirements: Vec<UnresolvedRequirementSpecification>,
requirements: Vec<UnnamedRequirement<VerbatimParsedUrl>>,
/// Whether to check hashes for distributions.
hasher: &'a HashStrategy,
/// The in-memory index for resolving dependencies.
Expand All @@ -49,7 +49,7 @@ pub struct NamedRequirementsResolver<'a, Context: BuildContext> {
impl<'a, Context: BuildContext> NamedRequirementsResolver<'a, Context> {
/// Instantiate a new [`NamedRequirementsResolver`] for a given set of requirements.
pub fn new(
requirements: Vec<UnresolvedRequirementSpecification>,
requirements: Vec<UnnamedRequirement<VerbatimParsedUrl>>,
hasher: &'a HashStrategy,
index: &'a InMemoryIndex,
database: DistributionDatabase<'a, Context>,
Expand Down Expand Up @@ -81,13 +81,10 @@ impl<'a, Context: BuildContext> NamedRequirementsResolver<'a, Context> {
} = self;
requirements
.into_iter()
.map(|entry| async {
match entry.requirement {
UnresolvedRequirement::Named(requirement) => Ok(requirement),
UnresolvedRequirement::Unnamed(requirement) => Ok(Requirement::from(
Self::resolve_requirement(requirement, hasher, index, &database).await?,
)),
}
.map(|requirement| async {
Self::resolve_requirement(requirement, hasher, index, &database)
.await
.map(Requirement::from)
})
.collect::<FuturesOrdered<_>>()
.try_collect()
Expand Down
79 changes: 59 additions & 20 deletions crates/uv/src/commands/pip/operations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use tracing::debug;

use distribution_types::{
CachedDist, Diagnostic, InstalledDist, LocalDist, NameRequirementSpecification,
ResolutionDiagnostic, UnresolvedRequirementSpecification,
ResolutionDiagnostic, UnresolvedRequirement, UnresolvedRequirementSpecification,
};
use distribution_types::{
DistributionMetadata, IndexLocations, InstalledMetadata, Name, Resolution,
Expand Down Expand Up @@ -116,16 +116,33 @@ pub(crate) async fn resolve<InstalledPackages: InstalledPackagesProvider>(

// Resolve the requirements from the provided sources.
let requirements = {
// Convert from unnamed to named requirements.
let mut requirements = NamedRequirementsResolver::new(
requirements,
hasher,
index,
DistributionDatabase::new(client, build_dispatch, concurrency.downloads),
)
.with_reporter(ResolverReporter::from(printer))
.resolve()
.await?;
// Partition the requirements into named and unnamed requirements.
let (mut requirements, unnamed): (Vec<_>, Vec<_>) =
requirements
.into_iter()
.partition_map(|spec| match spec.requirement {
UnresolvedRequirement::Named(requirement) => {
itertools::Either::Left(requirement)
}
UnresolvedRequirement::Unnamed(requirement) => {
itertools::Either::Right(requirement)
}
});

// Resolve any unnamed requirements.
if !unnamed.is_empty() {
requirements.extend(
NamedRequirementsResolver::new(
unnamed,
hasher,
index,
DistributionDatabase::new(client, build_dispatch, concurrency.downloads),
)
.with_reporter(ResolverReporter::from(printer))
.resolve()
.await?,
);
}

// Resolve any source trees into requirements.
if !source_trees.is_empty() {
Expand Down Expand Up @@ -183,15 +200,37 @@ pub(crate) async fn resolve<InstalledPackages: InstalledPackagesProvider>(
};

// Resolve the overrides from the provided sources.
let overrides = NamedRequirementsResolver::new(
overrides,
hasher,
index,
DistributionDatabase::new(client, build_dispatch, concurrency.downloads),
)
.with_reporter(ResolverReporter::from(printer))
.resolve()
.await?;
let overrides = {
// Partition the overrides into named and unnamed requirements.
let (mut overrides, unnamed): (Vec<_>, Vec<_>) =
overrides
.into_iter()
.partition_map(|spec| match spec.requirement {
UnresolvedRequirement::Named(requirement) => {
itertools::Either::Left(requirement)
}
UnresolvedRequirement::Unnamed(requirement) => {
itertools::Either::Right(requirement)
}
});

// Resolve any unnamed overrides.
if !unnamed.is_empty() {
overrides.extend(
NamedRequirementsResolver::new(
unnamed,
hasher,
index,
DistributionDatabase::new(client, build_dispatch, concurrency.downloads),
)
.with_reporter(ResolverReporter::from(printer))
.resolve()
.await?,
);
}

overrides
};

// Collect constraints and overrides.
let constraints = Constraints::from_requirements(
Expand Down
42 changes: 33 additions & 9 deletions crates/uv/src/commands/project/add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ use std::fmt::Write;
use std::path::{Path, PathBuf};

use anyhow::{bail, Context, Result};
use itertools::Itertools;
use owo_colors::OwoColorize;
use rustc_hash::{FxBuildHasher, FxHashMap};
use tracing::debug;

use cache_key::RepositoryUrl;
use distribution_types::UnresolvedRequirement;
use pep508_rs::{ExtraName, Requirement, VersionOrUrl};
use pypi_types::redact_git_credentials;
use uv_auth::{store_credentials_from_url, Credentials};
Expand Down Expand Up @@ -313,15 +315,37 @@ pub(crate) async fn add(
);

// Resolve any unnamed requirements.
let requirements = NamedRequirementsResolver::new(
requirements,
&hasher,
&state.index,
DistributionDatabase::new(&client, &build_dispatch, concurrency.downloads),
)
.with_reporter(ResolverReporter::from(printer))
.resolve()
.await?;
let requirements = {
// Partition the requirements into named and unnamed requirements.
let (mut requirements, unnamed): (Vec<_>, Vec<_>) =
requirements
.into_iter()
.partition_map(|spec| match spec.requirement {
UnresolvedRequirement::Named(requirement) => {
itertools::Either::Left(requirement)
}
UnresolvedRequirement::Unnamed(requirement) => {
itertools::Either::Right(requirement)
}
});

// Resolve any unnamed requirements.
if !unnamed.is_empty() {
requirements.extend(
NamedRequirementsResolver::new(
unnamed,
&hasher,
&state.index,
DistributionDatabase::new(&client, &build_dispatch, concurrency.downloads),
)
.with_reporter(ResolverReporter::from(printer))
.resolve()
.await?,
);
}

requirements
};

// Add the requirements to the `pyproject.toml` or script.
let mut toml = match &target {
Expand Down
40 changes: 30 additions & 10 deletions crates/uv/src/commands/project/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use itertools::Itertools;
use owo_colors::OwoColorize;
use tracing::debug;

use distribution_types::{Resolution, UnresolvedRequirementSpecification};
use distribution_types::{Resolution, UnresolvedRequirement, UnresolvedRequirementSpecification};
use pep440_rs::{Version, VersionSpecifiers};
use pep508_rs::MarkerTreeContents;
use pypi_types::Requirement;
Expand Down Expand Up @@ -548,6 +548,22 @@ pub(crate) async fn resolve_names(
cache: &Cache,
printer: Printer,
) -> anyhow::Result<Vec<Requirement>> {
// Partition the requirements into named and unnamed requirements.
let (mut requirements, unnamed): (Vec<_>, Vec<_>) =
requirements
.into_iter()
.partition_map(|spec| match spec.requirement {
UnresolvedRequirement::Named(requirement) => itertools::Either::Left(requirement),
UnresolvedRequirement::Unnamed(requirement) => {
itertools::Either::Right(requirement)
}
});

// Short-circuit if there are no unnamed requirements.
if unnamed.is_empty() {
return Ok(requirements);
}

// Extract the project settings.
let ResolverInstallerSettings {
index_locations,
Expand Down Expand Up @@ -627,16 +643,20 @@ pub(crate) async fn resolve_names(
concurrency,
);

// Initialize the resolver.
let resolver = NamedRequirementsResolver::new(
requirements,
&hasher,
&state.index,
DistributionDatabase::new(&client, &build_dispatch, concurrency.downloads),
)
.with_reporter(ResolverReporter::from(printer));
// Resolve the unnamed requirements.
requirements.extend(
NamedRequirementsResolver::new(
unnamed,
&hasher,
&state.index,
DistributionDatabase::new(&client, &build_dispatch, concurrency.downloads),
)
.with_reporter(ResolverReporter::from(printer))
.resolve()
.await?,
);

Ok(resolver.resolve().await?)
Ok(requirements)
}

/// Run dependency resolution for an interpreter, returning the [`ResolutionGraph`].
Expand Down

0 comments on commit aa71c89

Please sign in to comment.