Skip to content

Commit

Permalink
Track --no-build as an incompatibility
Browse files Browse the repository at this point in the history
Supersedes #2066
  • Loading branch information
zanieb committed Mar 7, 2024
1 parent cb36cf3 commit 1701d64
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 12 deletions.
1 change: 1 addition & 0 deletions crates/uv-dev/src/install_many.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ async fn install_chunk(
venv.interpreter(),
&FlatIndex::default(),
&NoBinary::None,
&NoBuild::None,
)
.resolve_stream(requirements)
.collect()
Expand Down
3 changes: 3 additions & 0 deletions crates/uv-resolver/src/candidate_selector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,9 @@ impl<'a> From<&'a PrioritizedDist> for CandidateDist<'a> {
if let Some(dist) = value.get() {
CandidateDist::Compatible(dist)
} else {
// TODO(zanieb): Here we always return the source distribution instead of the wheel
// if it exists. However, it may be helpful to return the wheel if it will lead to
// a clearer error message
let dist = if let Some((_, incompatibility)) = value.incompatible_source() {
IncompatibleDist::Source(incompatibility.clone())
} else if let Some((_, incompatibility)) = value.incompatible_wheel() {
Expand Down
12 changes: 10 additions & 2 deletions crates/uv-resolver/src/finder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use anyhow::Result;
use futures::{stream, Stream, StreamExt, TryStreamExt};
use rustc_hash::FxHashMap;
use uv_traits::NoBinary;
use uv_traits::{NoBinary, NoBuild};

use distribution_filename::DistFilename;
use distribution_types::{Dist, IndexUrl, Resolution};
Expand All @@ -26,6 +26,7 @@ pub struct DistFinder<'a> {
interpreter: &'a Interpreter,
flat_index: &'a FlatIndex,
no_binary: &'a NoBinary,
no_build: &'a NoBuild,
}

impl<'a> DistFinder<'a> {
Expand All @@ -36,6 +37,7 @@ impl<'a> DistFinder<'a> {
interpreter: &'a Interpreter,
flat_index: &'a FlatIndex,
no_binary: &'a NoBinary,
no_build: &'a NoBuild,
) -> Self {
Self {
tags,
Expand All @@ -44,6 +46,7 @@ impl<'a> DistFinder<'a> {
interpreter,
flat_index,
no_binary,
no_build,
}
}

Expand Down Expand Up @@ -135,6 +138,11 @@ impl<'a> DistFinder<'a> {
NoBinary::All => true,
NoBinary::Packages(packages) => packages.contains(&requirement.name),
};
let no_build = match self.no_build {
NoBuild::None => false,
NoBuild::All => true,
NoBuild::Packages(packages) => packages.contains(&requirement.name),
};

// Prioritize the flat index by initializing the "best" matches with its entries.
let matching_override = if let Some(flat_index) = flat_index {
Expand Down Expand Up @@ -215,7 +223,7 @@ impl<'a> DistFinder<'a> {
}

// Find the most-compatible sdist, if no wheel was found.
if best_wheel.is_none() {
if !no_build && best_wheel.is_none() {
for version_sdist in files.source_dists {
// Only add dists compatible with the python version.
// This is relevant for source dists which give no other indication of their
Expand Down
1 change: 1 addition & 0 deletions crates/uv-resolver/src/resolver/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ impl<'a, Context: BuildContext + Send + Sync> Resolver<'a, DefaultResolverProvid
AllowedYanks::from_manifest(&manifest, markers),
options.exclude_newer,
build_context.no_binary(),
build_context.no_build(),
);
Self::new_custom_io(
manifest,
Expand Down
6 changes: 5 additions & 1 deletion crates/uv-resolver/src/resolver/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use pypi_types::Metadata21;
use uv_client::{FlatIndex, RegistryClient};
use uv_distribution::DistributionDatabase;
use uv_normalize::PackageName;
use uv_traits::{BuildContext, NoBinary};
use uv_traits::{BuildContext, NoBinary, NoBuild};

use crate::python_requirement::PythonRequirement;
use crate::version_map::VersionMap;
Expand Down Expand Up @@ -70,6 +70,7 @@ pub struct DefaultResolverProvider<'a, Context: BuildContext + Send + Sync> {
allowed_yanks: AllowedYanks,
exclude_newer: Option<DateTime<Utc>>,
no_binary: NoBinary,
no_build: NoBuild,
}

impl<'a, Context: BuildContext + Send + Sync> DefaultResolverProvider<'a, Context> {
Expand All @@ -84,6 +85,7 @@ impl<'a, Context: BuildContext + Send + Sync> DefaultResolverProvider<'a, Contex
allowed_yanks: AllowedYanks,
exclude_newer: Option<DateTime<Utc>>,
no_binary: &'a NoBinary,
no_build: &'a NoBuild,
) -> Self {
Self {
fetcher,
Expand All @@ -94,6 +96,7 @@ impl<'a, Context: BuildContext + Send + Sync> DefaultResolverProvider<'a, Contex
allowed_yanks,
exclude_newer,
no_binary: no_binary.clone(),
no_build: no_build.clone(),
}
}
}
Expand Down Expand Up @@ -121,6 +124,7 @@ impl<'a, Context: BuildContext + Send + Sync> ResolverProvider
self.exclude_newer.as_ref(),
self.flat_index.get(package_name).cloned(),
&self.no_binary,
&self.no_build,
))),
Err(err) => match err.into_kind() {
uv_client::ErrorKind::PackageNotFound(_) => {
Expand Down
19 changes: 16 additions & 3 deletions crates/uv-resolver/src/version_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use pypi_types::Hashes;
use rkyv::{de::deserializers::SharedDeserializeMap, Deserialize};
use uv_client::{FlatDistributions, OwnedArchive, SimpleMetadata, VersionFiles};
use uv_normalize::PackageName;
use uv_traits::NoBinary;
use uv_traits::{NoBinary, NoBuild};
use uv_warnings::warn_user_once;

use crate::{python_requirement::PythonRequirement, yanks::AllowedYanks};
Expand Down Expand Up @@ -48,6 +48,7 @@ impl VersionMap {
exclude_newer: Option<&DateTime<Utc>>,
flat_index: Option<FlatDistributions>,
no_binary: &NoBinary,
no_build: &NoBuild,
) -> Self {
let mut map = BTreeMap::new();
// Create stubs for each entry in simple metadata. The full conversion
Expand Down Expand Up @@ -96,12 +97,18 @@ impl VersionMap {
NoBinary::None => false,
NoBinary::All => true,
NoBinary::Packages(packages) => packages.contains(package_name),
}; // Check if source distributions are allowed for this package.
let no_build = match no_build {
NoBuild::None => false,
NoBuild::All => true,
NoBuild::Packages(packages) => packages.contains(package_name),
};
Self {
inner: VersionMapInner::Lazy(VersionMapLazy {
map,
simple_metadata,
no_binary,
no_build,
index: index.clone(),
tags: tags.clone(),
python_requirement: python_requirement.clone(),
Expand Down Expand Up @@ -269,6 +276,8 @@ struct VersionMapLazy {
simple_metadata: OwnedArchive<SimpleMetadata>,
/// When true, wheels aren't allowed.
no_binary: bool,
/// When true, source dists aren't allowed.
no_build: bool,
/// The URL of the index where this package came from.
index: IndexUrl,
/// The set of compatibility tags that determines whether a wheel is usable
Expand Down Expand Up @@ -414,7 +423,11 @@ impl VersionMapLazy {
file,
self.index.clone(),
);
let mut compatibility = SourceDistCompatibility::Compatible;
let mut compatibility = if self.no_build {
SourceDistCompatibility::Incompatible(IncompatibleSource::NoBuild)
} else {
SourceDistCompatibility::Compatible
};

if excluded {
// Treat as incompatible if after upload time cutoff
Expand Down Expand Up @@ -468,7 +481,7 @@ enum LazyPrioritizedDist {
/// Represents a eagerly constructed distribution from a
/// `FlatDistributions`.
OnlyFlat(PrioritizedDist),
/// Represents a lazyily constructed distribution from an index into a
/// Represents a lazily constructed distribution from an index into a
/// `VersionFiles` from `SimpleMetadata`.
OnlySimple(SimplePrioritizedDist),
/// Combines the above. This occurs when we have data from both a flat
Expand Down
12 changes: 9 additions & 3 deletions crates/uv/src/commands/pip_sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,9 +220,15 @@ pub(crate) async fn pip_sync(
} else {
let start = std::time::Instant::now();

let wheel_finder =
uv_resolver::DistFinder::new(tags, &client, venv.interpreter(), &flat_index, no_binary)
.with_reporter(FinderReporter::from(printer).with_length(remote.len() as u64));
let wheel_finder = uv_resolver::DistFinder::new(
tags,
&client,
venv.interpreter(),
&flat_index,
no_binary,
no_build,
)
.with_reporter(FinderReporter::from(printer).with_length(remote.len() as u64));
let resolution = wheel_finder.resolve(&remote).await?;

let s = if resolution.len() == 1 { "" } else { "s" };
Expand Down
7 changes: 4 additions & 3 deletions crates/uv/tests/pip_install_scenarios.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3445,12 +3445,13 @@ fn no_wheels_no_build() {
.arg("no-wheels-no-build-a")
, @r###"
success: false
exit_code: 2
exit_code: 1
----- stdout -----
----- stderr -----
error: Failed to download and build: albatross==1.0.0
Caused by: Building source distributions is disabled
× No solution found when resolving dependencies:
╰─▶ Because only albatross==1.0.0 is available and albatross==1.0.0 is unusable because no wheels are available and building from source is disabled, we can conclude that all versions of albatross cannot be used.
And because you require albatross, we can conclude that the requirements are unsatisfiable.
"###);

assert_not_installed(&context.venv, "no_wheels_no_build_a", &context.temp_dir);
Expand Down

0 comments on commit 1701d64

Please sign in to comment.