Add resolver error hint for no-binary and no-build failures (#9948)
Some checks are pending
CI / check system | python on macos x86_64 (push) Blocked by required conditions
CI / build binary | macos x86_64 (push) Blocked by required conditions
CI / Determine changes (push) Waiting to run
CI / check windows trampoline | i686 (push) Blocked by required conditions
CI / lint (push) Waiting to run
CI / cargo clippy | ubuntu (push) Blocked by required conditions
CI / cargo clippy | windows (push) Blocked by required conditions
CI / cargo dev generate-all (push) Blocked by required conditions
CI / cargo shear (push) Waiting to run
CI / build binary | macos aarch64 (push) Blocked by required conditions
CI / cargo test | ubuntu (push) Blocked by required conditions
CI / cargo test | macos (push) Blocked by required conditions
CI / cargo test | windows (push) Blocked by required conditions
CI / check windows trampoline | aarch64 (push) Blocked by required conditions
CI / check windows trampoline | x86_64 (push) Blocked by required conditions
CI / test windows trampoline | i686 (push) Blocked by required conditions
CI / test windows trampoline | x86_64 (push) Blocked by required conditions
CI / typos (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / build binary | linux (push) Blocked by required conditions
CI / build binary | windows (push) Blocked by required conditions
CI / cargo build (msrv) (push) Blocked by required conditions
CI / build binary | freebsd (push) Blocked by required conditions
CI / ecosystem test | prefecthq/prefect (push) Blocked by required conditions
CI / ecosystem test | pallets/flask (push) Blocked by required conditions
CI / integration test | conda on ubuntu (push) Blocked by required conditions
CI / integration test | free-threaded on linux (push) Blocked by required conditions
CI / integration test | free-threaded on windows (push) Blocked by required conditions
CI / integration test | pypy on ubuntu (push) Blocked by required conditions
CI / integration test | pypy on windows (push) Blocked by required conditions
CI / integration test | graalpy on ubuntu (push) Blocked by required conditions
CI / integration test | graalpy on windows (push) Blocked by required conditions
CI / integration test | github actions (push) Blocked by required conditions
CI / integration test | determine publish changes (push) Blocked by required conditions
CI / integration test | uv publish (push) Blocked by required conditions
CI / check cache | ubuntu (push) Blocked by required conditions
CI / check cache | macos aarch64 (push) Blocked by required conditions
CI / check system | python on debian (push) Blocked by required conditions
CI / check system | python on fedora (push) Blocked by required conditions
CI / check system | python on ubuntu (push) Blocked by required conditions
CI / check system | python on opensuse (push) Blocked by required conditions
CI / check system | homebrew python on macos aarch64 (push) Blocked by required conditions
CI / check system | python on rocky linux 8 (push) Blocked by required conditions
CI / check system | python on rocky linux 9 (push) Blocked by required conditions
CI / check system | pypy on ubuntu (push) Blocked by required conditions
CI / check system | pyston (push) Blocked by required conditions
CI / check system | alpine (push) Blocked by required conditions
CI / check system | python on macos aarch64 (push) Blocked by required conditions
CI / check system | python3.10 on windows (push) Blocked by required conditions
CI / check system | python3.10 on windows x86 (push) Blocked by required conditions
CI / check system | python3.13 on windows (push) Blocked by required conditions
CI / check system | python3.12 via chocolatey (push) Blocked by required conditions
CI / check system | python3.9 via pyenv (push) Blocked by required conditions
CI / check system | python3.13 (push) Blocked by required conditions
CI / check system | conda3.11 on linux (push) Blocked by required conditions
CI / check system | conda3.8 on linux (push) Blocked by required conditions
CI / check system | conda3.11 on macos (push) Blocked by required conditions
CI / check system | conda3.8 on macos (push) Blocked by required conditions
CI / check system | conda3.11 on windows (push) Blocked by required conditions
CI / check system | conda3.8 on windows (push) Blocked by required conditions
CI / check system | amazonlinux (push) Blocked by required conditions
CI / check system | embedded python3.10 on windows (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions

Moves some of the context out of the error chain to improve readability.
This commit is contained in:
Zanie Blue 2024-12-16 18:47:40 -06:00 committed by GitHub
parent 160fc37315
commit d257bea720
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 106 additions and 16 deletions

View file

@ -142,9 +142,7 @@ impl Display for IncompatibleDist {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Self::Wheel(incompatibility) => match incompatibility {
IncompatibleWheel::NoBinary => {
f.write_str("no source distribution and using wheels is disabled")
}
IncompatibleWheel::NoBinary => f.write_str("no source distribution"),
IncompatibleWheel::Tag(tag) => match tag {
IncompatibleTag::Invalid => f.write_str("no wheels with valid tags"),
IncompatibleTag::Python => {
@ -175,9 +173,7 @@ impl Display for IncompatibleDist {
}
},
Self::Source(incompatibility) => match incompatibility {
IncompatibleSource::NoBuild => {
f.write_str("no usable wheels and building from source is disabled")
}
IncompatibleSource::NoBuild => f.write_str("no usable wheels"),
IncompatibleSource::Yanked(yanked) => match yanked {
Yanked::Bool(_) => f.write_str("yanked"),
Yanked::Reason(reason) => write!(

View file

@ -9,7 +9,10 @@ use pubgrub::{DerivationTree, Derived, External, Map, Range, ReportFormatter, Te
use rustc_hash::FxHashMap;
use uv_configuration::IndexStrategy;
use uv_distribution_types::{Index, IndexCapabilities, IndexLocations, IndexUrl};
use uv_distribution_types::{
IncompatibleDist, IncompatibleSource, IncompatibleWheel, Index, IndexCapabilities,
IndexLocations, IndexUrl,
};
use uv_normalize::PackageName;
use uv_pep440::{Version, VersionSpecifiers};
@ -18,7 +21,9 @@ use crate::error::ErrorTree;
use crate::fork_urls::ForkUrls;
use crate::prerelease::AllowPrerelease;
use crate::python_requirement::{PythonRequirement, PythonRequirementSource};
use crate::resolver::{MetadataUnavailable, UnavailablePackage, UnavailableReason};
use crate::resolver::{
MetadataUnavailable, UnavailablePackage, UnavailableReason, UnavailableVersion,
};
use crate::{Flexibility, Options, RequiresPython, ResolverEnvironment};
use super::{PubGrubPackage, PubGrubPackageInner, PubGrubPython};
@ -556,9 +561,58 @@ impl PubGrubReportFormatter<'_> {
output_hints: &mut IndexSet<PubGrubHint>,
) {
match derivation_tree {
DerivationTree::External(
External::Custom(package, set, _) | External::NoVersions(package, set),
) => {
DerivationTree::External(External::Custom(package, set, reason)) => {
if let PubGrubPackageInner::Package { name, .. } = &**package {
// Check for no versions due to pre-release options.
if options.flexibility == Flexibility::Configurable {
if !fork_urls.contains_key(name) {
self.prerelease_available_hint(
package,
name,
set,
selector,
env,
output_hints,
);
}
}
// Check for no versions due to no `--find-links` flat index.
Self::index_hints(
package,
name,
set,
selector,
index_locations,
index_capabilities,
available_indexes,
unavailable_packages,
incomplete_packages,
output_hints,
);
}
// Check for unavailable versions due to `--no-build` or `--no-binary`.
if let UnavailableReason::Version(UnavailableVersion::IncompatibleDist(
incompatibility,
)) = reason
{
match incompatibility {
IncompatibleDist::Wheel(IncompatibleWheel::NoBinary) => {
output_hints.insert(PubGrubHint::NoBinary {
package: package.clone(),
});
}
IncompatibleDist::Source(IncompatibleSource::NoBuild) => {
output_hints.insert(PubGrubHint::NoBuild {
package: package.clone(),
});
}
_ => {}
}
}
}
DerivationTree::External(External::NoVersions(package, set)) => {
if let PubGrubPackageInner::Package { name, .. } = &**package {
// Check for no versions due to pre-release options.
if options.flexibility == Flexibility::Configurable {
@ -954,6 +1008,10 @@ pub(crate) enum PubGrubHint {
// excluded from `PartialEq` and `Hash`
next_index: IndexUrl,
},
/// No wheels are available for a package, and using source distributions was disabled.
NoBuild { package: PubGrubPackage },
/// No source distributions are available for a package, and using pre-built wheels was disabled.
NoBinary { package: PubGrubPackage },
/// An index returned an Unauthorized (401) response.
UnauthorizedIndex { index: IndexUrl },
/// An index returned a Forbidden (403) response.
@ -1013,6 +1071,12 @@ enum PubGrubHintCore {
ForbiddenIndex {
index: IndexUrl,
},
NoBuild {
package: PubGrubPackage,
},
NoBinary {
package: PubGrubPackage,
},
}
impl From<PubGrubHint> for PubGrubHintCore {
@ -1068,6 +1132,8 @@ impl From<PubGrubHint> for PubGrubHintCore {
PubGrubHint::UncheckedIndex { package, .. } => Self::UncheckedIndex { package },
PubGrubHint::UnauthorizedIndex { index } => Self::UnauthorizedIndex { index },
PubGrubHint::ForbiddenIndex { index } => Self::ForbiddenIndex { index },
PubGrubHint::NoBuild { package } => Self::NoBuild { package },
PubGrubHint::NoBinary { package } => Self::NoBinary { package },
}
}
}
@ -1342,6 +1408,24 @@ impl std::fmt::Display for PubGrubHint {
"403 Forbidden".red(),
)
}
Self::NoBuild { package } => {
write!(
f,
"{}{} Wheels are required for `{}` because building from source is disabled",
"hint".bold().cyan(),
":".bold(),
package.cyan(),
)
}
Self::NoBinary { package } => {
write!(
f,
"{}{} A source distributions is required for `{}` because using pre-built wheels is disabled",
"hint".bold().cyan(),
":".bold(),
package.cyan(),
)
}
}
}
}

View file

@ -12807,8 +12807,10 @@ fn no_binary_only_binary() -> Result<()> {
----- stderr -----
× No solution found when resolving dependencies:
Because only source-distribution>=0.0.1 is available and source-distribution==0.0.1 has no usable wheels and building from source is disabled, we can conclude that source-distribution<=0.0.1 cannot be used.
Because only source-distribution>=0.0.1 is available and source-distribution==0.0.1 has no usable wheels, we can conclude that source-distribution<=0.0.1 cannot be used.
And because you require source-distribution<=0.0.1, we can conclude that your requirements are unsatisfiable.
hint: Wheels are required for `source-distribution` because building from source is disabled
"###
);

View file

@ -2181,7 +2181,7 @@ fn install_only_binary_all_and_no_binary_all() {
anyio>=3.0.0,<=3.6.2
anyio>=3.7.0,<=3.7.1
anyio>=4.0.0
have no usable wheels and building from source is disabled, we can conclude that all of:
have no usable wheels, we can conclude that all of:
anyio>=1.0.0,<=1.4.0
anyio>=2.0.0,<=2.2.0
anyio>=3.0.0,<=3.6.2
@ -2191,6 +2191,8 @@ fn install_only_binary_all_and_no_binary_all() {
And because you require anyio, we can conclude that your requirements are unsatisfiable.
hint: Pre-releases are available for `anyio` in the requested range (e.g., 4.0.0rc1), but pre-releases weren't enabled (try: `--prerelease=allow`)
hint: Wheels are required for `anyio` because building from source is disabled
"###
);
@ -2281,7 +2283,9 @@ fn only_binary_requirements_txt() {
----- stderr -----
× No solution found when resolving dependencies:
Because django-allauth==0.51.0 has no usable wheels and building from source is disabled and you require django-allauth==0.51.0, we can conclude that your requirements are unsatisfiable.
Because django-allauth==0.51.0 has no usable wheels and you require django-allauth==0.51.0, we can conclude that your requirements are unsatisfiable.
hint: Wheels are required for `django-allauth` because building from source is disabled
"###
);
}

View file

@ -4202,8 +4202,10 @@ fn no_wheels_no_build() {
----- stderr -----
× No solution found when resolving dependencies:
Because only package-a==1.0.0 is available and package-a==1.0.0 has no usable wheels and building from source is disabled, we can conclude that all versions of package-a cannot be used.
Because only package-a==1.0.0 is available and package-a==1.0.0 has no usable wheels, we can conclude that all versions of package-a cannot be used.
And because you require package-a, we can conclude that your requirements are unsatisfiable.
hint: Wheels are required for `package-a` because building from source is disabled
"###);
assert_not_installed(&context.venv, "no_wheels_no_build_a", &context.temp_dir);
@ -4310,8 +4312,10 @@ fn only_wheels_no_binary() {
----- stderr -----
× No solution found when resolving dependencies:
Because only package-a==1.0.0 is available and package-a==1.0.0 has no source distribution and using wheels is disabled, we can conclude that all versions of package-a cannot be used.
Because only package-a==1.0.0 is available and package-a==1.0.0 has no source distribution, we can conclude that all versions of package-a cannot be used.
And because you require package-a, we can conclude that your requirements are unsatisfiable.
hint: A source distributions is required for `package-a` because using pre-built wheels is disabled
"###);
assert_not_installed(&context.venv, "only_wheels_no_binary_a", &context.temp_dir);