mirror of
https://github.com/astral-sh/uv.git
synced 2025-08-04 10:58:28 +00:00
Invert display of "no versions" incompatibilities with multiple ranges (#1233)
Closes #884 e.g. ``` ❯ cargo run -q -- pip compile --python-version 3.12 requirements.in × No solution found when resolving dependencies: ╰─▶ Because the requested Python version (3.12) does not satisfy Python>=3.6,<3.10 and recommenders==1.0.0 depends on Python>=3.6,<3.9, we can conclude that recommenders==1.0.0 cannot be used. And because only the following versions of recommenders are available: recommenders<=0.7 recommenders==1.0.0 recommenders==1.1.0 recommenders==1.1.1 we can conclude that recommenders>0.7,<1.1.0 cannot be used. (1) Because the requested Python version (3.12) does not satisfy Python>=3.6,<3.10 and recommenders>=1.1.0 depends on Python>=3.6,<3.10, we can conclude that recommenders>=1.1.0 cannot be used. And because we know from (1) that recommenders>0.7,<1.1.0 cannot be used, we can conclude that recommenders>0.7 cannot be used. And because you require recommenders>0.7, we can conclude that the requirements are unsatisfiable. ```
This commit is contained in:
parent
e3c1586310
commit
6db9db0079
4 changed files with 53 additions and 42 deletions
|
@ -82,16 +82,18 @@ impl ReportFormatter<PubGrubPackage, Range<Version>> for PubGrubReportFormatter<
|
|||
} else {
|
||||
let complement = set.complement();
|
||||
let segments = complement.iter().collect::<Vec<_>>().len();
|
||||
// Simple case, there's a single range to report
|
||||
if segments == 1 {
|
||||
format!(
|
||||
"only {} is available",
|
||||
PackageRange::compatibility(package, &complement)
|
||||
)
|
||||
// Complex case, there are multiple ranges
|
||||
} else {
|
||||
format!(
|
||||
"there are no versions of {} that satisfy {}",
|
||||
"only the following versions of {} {}",
|
||||
package,
|
||||
PackageRange::compatibility(package, &set)
|
||||
PackageRange::available(package, &complement)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -485,6 +487,7 @@ impl PackageTerm<'_> {
|
|||
enum PackageRangeKind {
|
||||
Dependency,
|
||||
Compatibility,
|
||||
Available,
|
||||
}
|
||||
|
||||
/// A [`Range`] and [`PubGrubPackage`] combination for display.
|
||||
|
@ -520,6 +523,7 @@ impl std::fmt::Display for PackageRange<'_> {
|
|||
match self.kind {
|
||||
PackageRangeKind::Dependency => write!(f, "one of:")?,
|
||||
PackageRangeKind::Compatibility => write!(f, "any of:")?,
|
||||
PackageRangeKind::Available => write!(f, "are available:")?,
|
||||
}
|
||||
}
|
||||
for segment in &segments {
|
||||
|
@ -531,6 +535,7 @@ impl std::fmt::Display for PackageRange<'_> {
|
|||
(Bound::Unbounded, Bound::Unbounded) => match self.kind {
|
||||
PackageRangeKind::Dependency => write!(f, "{package}")?,
|
||||
PackageRangeKind::Compatibility => write!(f, "all versions of {package}")?,
|
||||
PackageRangeKind::Available => write!(f, "{package}")?,
|
||||
},
|
||||
(Bound::Unbounded, Bound::Included(v)) => write!(f, "{package}<={v}")?,
|
||||
(Bound::Unbounded, Bound::Excluded(v)) => write!(f, "{package}<{v}")?,
|
||||
|
@ -576,6 +581,13 @@ impl PackageRange<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
fn available<'a>(package: &'a PubGrubPackage, range: &'a Range<Version>) -> PackageRange<'a> {
|
||||
PackageRange {
|
||||
package,
|
||||
range,
|
||||
kind: PackageRangeKind::Available,
|
||||
}
|
||||
}
|
||||
fn depends_on<'a>(
|
||||
&'a self,
|
||||
package: &'a PubGrubPackage,
|
||||
|
|
|
@ -1743,16 +1743,18 @@ fn compile_yanked_version_indirect() -> Result<()> {
|
|||
|
||||
puffin_snapshot!(context.compile()
|
||||
.arg("requirements.in"), @r###"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
× No solution found when resolving dependencies:
|
||||
╰─▶ Because there are no versions of attrs that satisfy attrs>20.3.0,<21.2.0
|
||||
and you require attrs>20.3.0,<21.2.0, we can conclude that the
|
||||
requirements are unsatisfiable.
|
||||
"###
|
||||
----- stderr -----
|
||||
× No solution found when resolving dependencies:
|
||||
╰─▶ Because only the following versions of attrs are available:
|
||||
attrs<=20.3.0
|
||||
attrs>=21.2.0
|
||||
and you require attrs>20.3.0,<21.2.0, we can conclude that the
|
||||
requirements are unsatisfiable.
|
||||
"###
|
||||
);
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -375,10 +375,9 @@ fn requires_incompatible_python_version_compatible_override_other_wheel() -> Res
|
|||
warning: The requested Python version 3.11 is not available; 3.9.18 will be used to build dependencies instead.
|
||||
× No solution found when resolving dependencies:
|
||||
╰─▶ Because the current Python version (3.9.18) does not satisfy Python>=3.10 and albatross==1.0.0 depends on Python>=3.10, we can conclude that albatross==1.0.0 cannot be used.
|
||||
And because there are no versions of albatross that satisfy any of:
|
||||
albatross<1.0.0
|
||||
albatross>1.0.0,<2.0.0
|
||||
albatross>2.0.0
|
||||
And because only the following versions of albatross are available:
|
||||
albatross==1.0.0
|
||||
albatross==2.0.0
|
||||
we can conclude that albatross<2.0.0 cannot be used. (1)
|
||||
|
||||
Because the requested Python version (3.11) does not satisfy Python>=3.12 and albatross==2.0.0 depends on Python>=3.12, we can conclude that albatross==2.0.0 cannot be used.
|
||||
|
|
|
@ -340,11 +340,10 @@ fn excluded_only_compatible_version() {
|
|||
|
||||
----- stderr -----
|
||||
× No solution found when resolving dependencies:
|
||||
╰─▶ Because there are no versions of albatross that satisfy any of:
|
||||
albatross<1.0.0
|
||||
albatross>1.0.0,<2.0.0
|
||||
albatross>2.0.0,<3.0.0
|
||||
albatross>3.0.0
|
||||
╰─▶ Because only the following versions of albatross are available:
|
||||
albatross==1.0.0
|
||||
albatross==2.0.0
|
||||
albatross==3.0.0
|
||||
and albatross==1.0.0 depends on bluebird==1.0.0, we can conclude that albatross<2.0.0 depends on bluebird==1.0.0.
|
||||
And because albatross==3.0.0 depends on bluebird==3.0.0, we can conclude that any of:
|
||||
albatross<2.0.0
|
||||
|
@ -441,15 +440,14 @@ fn dependency_excludes_range_of_compatible_versions() {
|
|||
|
||||
----- stderr -----
|
||||
× No solution found when resolving dependencies:
|
||||
╰─▶ Because there are no versions of crow that satisfy any of:
|
||||
crow<1.0.0
|
||||
crow>1.0.0,<2.0.0
|
||||
crow>2.0.0
|
||||
╰─▶ Because only the following versions of crow are available:
|
||||
crow==1.0.0
|
||||
crow==2.0.0
|
||||
and crow==1.0.0 depends on albatross<2.0.0, we can conclude that crow<2.0.0 depends on albatross<2.0.0. (1)
|
||||
|
||||
Because there are no versions of albatross that satisfy any of:
|
||||
albatross<1.0.0
|
||||
albatross>1.0.0,<2.0.0
|
||||
Because only the following versions of albatross are available:
|
||||
albatross==1.0.0
|
||||
albatross>=2.0.0
|
||||
and albatross==1.0.0 depends on bluebird==1.0.0, we can conclude that albatross<2.0.0 depends on bluebird==1.0.0.
|
||||
And because we know from (1) that crow<2.0.0 depends on albatross<2.0.0, we can conclude that crow<2.0.0 depends on bluebird==1.0.0.
|
||||
And because crow==2.0.0 depends on albatross>=3.0.0, we can conclude that all versions of crow, bluebird!=1.0.0, albatross<3.0.0 are incompatible. (2)
|
||||
|
@ -556,15 +554,14 @@ fn dependency_excludes_non_contiguous_range_of_compatible_versions() {
|
|||
|
||||
----- stderr -----
|
||||
× No solution found when resolving dependencies:
|
||||
╰─▶ Because there are no versions of crow that satisfy any of:
|
||||
crow<1.0.0
|
||||
crow>1.0.0,<2.0.0
|
||||
crow>2.0.0
|
||||
╰─▶ Because only the following versions of crow are available:
|
||||
crow==1.0.0
|
||||
crow==2.0.0
|
||||
and crow==1.0.0 depends on albatross<2.0.0, we can conclude that crow<2.0.0 depends on albatross<2.0.0. (1)
|
||||
|
||||
Because there are no versions of albatross that satisfy any of:
|
||||
albatross<1.0.0
|
||||
albatross>1.0.0,<2.0.0
|
||||
Because only the following versions of albatross are available:
|
||||
albatross==1.0.0
|
||||
albatross>=2.0.0
|
||||
and albatross==1.0.0 depends on bluebird==1.0.0, we can conclude that albatross<2.0.0 depends on bluebird==1.0.0.
|
||||
And because we know from (1) that crow<2.0.0 depends on albatross<2.0.0, we can conclude that crow<2.0.0 depends on bluebird==1.0.0.
|
||||
And because crow==2.0.0 depends on albatross>=3.0.0, we can conclude that all versions of crow, bluebird!=1.0.0, albatross<3.0.0 are incompatible. (2)
|
||||
|
@ -1938,10 +1935,11 @@ fn transitive_prerelease_and_stable_dependency_many_versions_holes() {
|
|||
|
||||
----- stderr -----
|
||||
× No solution found when resolving dependencies:
|
||||
╰─▶ Because there are no versions of crow that satisfy any of:
|
||||
crow>1.0.0,<2.0.0a5
|
||||
crow>2.0.0a7,<2.0.0b1
|
||||
crow>2.0.0b1,<2.0.0b5
|
||||
╰─▶ Because only the following versions of crow are available:
|
||||
crow<=1.0.0
|
||||
crow>=2.0.0a5,<=2.0.0a7
|
||||
crow==2.0.0b1
|
||||
crow>=2.0.0b5
|
||||
and albatross==1.0.0 depends on one of:
|
||||
crow>1.0.0,<2.0.0a5
|
||||
crow>2.0.0a7,<2.0.0b1
|
||||
|
@ -2282,10 +2280,10 @@ fn requires_python_version_greater_than_current_excluded() {
|
|||
Python>=3.12
|
||||
are incompatible.
|
||||
And because the current Python version (3.9.18) does not satisfy Python>=3.11,<3.12, we can conclude that Python>=3.10 are incompatible.
|
||||
And because albatross==2.0.0 depends on Python>=3.10 and there are no versions of albatross that satisfy any of:
|
||||
albatross>2.0.0,<3.0.0
|
||||
albatross>3.0.0,<4.0.0
|
||||
albatross>4.0.0
|
||||
And because albatross==2.0.0 depends on Python>=3.10 and only the following versions of albatross are available:
|
||||
albatross<=2.0.0
|
||||
albatross==3.0.0
|
||||
albatross==4.0.0
|
||||
we can conclude that albatross>=2.0.0,<3.0.0 cannot be used. (1)
|
||||
|
||||
Because the current Python version (3.9.18) does not satisfy Python>=3.11,<3.12 and the current Python version (3.9.18) does not satisfy Python>=3.12, we can conclude that Python>=3.11 are incompatible.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue