mirror of https://github.com/astral-sh/uv
Fix inclusive constraints on available package versions in resolver errors (#16629)
Closes https://github.com/astral-sh/uv/issues/16626
This commit is contained in:
parent
5e181d36ef
commit
bfecc9902e
|
|
@ -1895,6 +1895,23 @@ fn update_availability_range(
|
|||
range: &Range<Version>,
|
||||
available_versions: &BTreeSet<Version>,
|
||||
) -> Range<Version> {
|
||||
/// Whether a (normalized) version is contained in a set of versions.
|
||||
///
|
||||
/// Unfortunately, we need to normalize the version because when we extract it from the range it
|
||||
/// may have `min` or `max` set but the values in `available_versions` will never have `min` or
|
||||
/// `max`.
|
||||
fn version_contained_in(version: &Version, versions: &BTreeSet<Version>) -> bool {
|
||||
if versions.contains(version) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// It's a little unfortunate we perform a clone here and throw away the value, but the
|
||||
// performance implications during an error report seem negligible and it makes the
|
||||
// calling code simpler.
|
||||
let version = version.clone().with_min(None).with_max(None);
|
||||
versions.contains(&version)
|
||||
}
|
||||
|
||||
let mut new_range = Range::empty();
|
||||
|
||||
// Construct an available range to help guide simplification. Note this is not strictly correct,
|
||||
|
|
@ -1957,13 +1974,13 @@ fn update_availability_range(
|
|||
// bound to avoid confusion, e.g., if the segment is `foo<=10` and the available versions
|
||||
// do not include `foo 10`, we should instead say `foo<10`.
|
||||
let lower = match lower {
|
||||
Bound::Included(version) if !available_versions.contains(version) => {
|
||||
Bound::Included(version) if !version_contained_in(version, available_versions) => {
|
||||
Bound::Excluded(version.clone())
|
||||
}
|
||||
_ => (*lower).clone(),
|
||||
};
|
||||
let upper = match upper {
|
||||
Bound::Included(version) if !available_versions.contains(version) => {
|
||||
Bound::Included(version) if !version_contained_in(version, available_versions) => {
|
||||
Bound::Excluded(version.clone())
|
||||
}
|
||||
_ => (*upper).clone(),
|
||||
|
|
|
|||
|
|
@ -783,7 +783,7 @@ fn conflict_in_fork() -> Result<()> {
|
|||
And because package-a==1.0.0 depends on package-b and package-c, we can conclude that package-a==1.0.0 cannot be used.
|
||||
And because only the following versions of package-a{sys_platform == 'os2'} are available:
|
||||
package-a{sys_platform == 'os2'}==1.0.0
|
||||
package-a{sys_platform == 'os2'}>2
|
||||
package-a{sys_platform == 'os2'}>=2
|
||||
and your project depends on package-a{sys_platform == 'os2'}<2, we can conclude that your project's requirements are unsatisfiable.
|
||||
|
||||
hint: The resolution failed for an environment that is not the current one, consider limiting the environments with `tool.uv.environments`.
|
||||
|
|
|
|||
|
|
@ -3952,7 +3952,7 @@ fn compile_yanked_version_indirect() -> Result<()> {
|
|||
requirements_in.write_str("attrs>20.3.0,<21.2.0")?;
|
||||
|
||||
uv_snapshot!(context.filters(), context.pip_compile()
|
||||
.arg("requirements.in"), @r###"
|
||||
.arg("requirements.in"), @r"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
|
|
@ -3960,12 +3960,12 @@ fn compile_yanked_version_indirect() -> Result<()> {
|
|||
----- stderr -----
|
||||
× No solution found when resolving dependencies:
|
||||
╰─▶ Because only the following versions of attrs are available:
|
||||
attrs<20.3.0
|
||||
attrs<=20.3.0
|
||||
attrs==21.1.0
|
||||
attrs>21.2.0
|
||||
attrs>=21.2.0
|
||||
and attrs==21.1.0 was yanked (reason: Installable but not importable on Python 3.4), we can conclude that attrs>20.3.0,<21.2.0 cannot be used.
|
||||
And because you require attrs>20.3.0,<21.2.0, we can conclude that your requirements are unsatisfiable.
|
||||
"###
|
||||
"
|
||||
);
|
||||
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -3719,7 +3719,7 @@ fn build_prerelease_hint() -> Result<()> {
|
|||
× Failed to build `project @ file://[TEMP_DIR]/`
|
||||
├─▶ Failed to resolve requirements from `build-system.requires`
|
||||
├─▶ No solution found when resolving: `transitive-package-only-prereleases-in-range-a`
|
||||
╰─▶ Because only transitive-package-only-prereleases-in-range-b<0.1 is available and transitive-package-only-prereleases-in-range-a==0.1.0 depends on transitive-package-only-prereleases-in-range-b>0.1, we can conclude that transitive-package-only-prereleases-in-range-a==0.1.0 cannot be used.
|
||||
╰─▶ Because only transitive-package-only-prereleases-in-range-b<=0.1 is available and transitive-package-only-prereleases-in-range-a==0.1.0 depends on transitive-package-only-prereleases-in-range-b>0.1, we can conclude that transitive-package-only-prereleases-in-range-a==0.1.0 cannot be used.
|
||||
And because only transitive-package-only-prereleases-in-range-a==0.1.0 is available and you require transitive-package-only-prereleases-in-range-a, we can conclude that your requirements are unsatisfiable.
|
||||
|
||||
hint: Only pre-releases of `transitive-package-only-prereleases-in-range-b` (e.g., 1.0.0a1) match these build requirements, and build environments can't enable pre-releases automatically. Add `transitive-package-only-prereleases-in-range-b>=1.0.0a1` to `build-system.requires`, `[tool.uv.extra-build-dependencies]`, or supply it via `uv build --build-constraint`.
|
||||
|
|
|
|||
|
|
@ -284,7 +284,7 @@ fn dependency_excludes_non_contiguous_range_of_compatible_versions() {
|
|||
× No solution found when resolving dependencies:
|
||||
╰─▶ Because package-a==1.0.0 depends on package-b==1.0.0 and only the following versions of package-a are available:
|
||||
package-a==1.0.0
|
||||
package-a>2.0.0
|
||||
package-a>=2.0.0
|
||||
we can conclude that package-a<2.0.0 depends on package-b==1.0.0.
|
||||
And because only package-a<=3.0.0 is available, we can conclude that package-a<2.0.0 depends on package-b==1.0.0. (1)
|
||||
|
||||
|
|
@ -387,7 +387,7 @@ fn dependency_excludes_range_of_compatible_versions() {
|
|||
× No solution found when resolving dependencies:
|
||||
╰─▶ Because package-a==1.0.0 depends on package-b==1.0.0 and only the following versions of package-a are available:
|
||||
package-a==1.0.0
|
||||
package-a>2.0.0
|
||||
package-a>=2.0.0
|
||||
we can conclude that package-a<2.0.0 depends on package-b==1.0.0.
|
||||
And because only package-a<=3.0.0 is available, we can conclude that package-a<2.0.0 depends on package-b==1.0.0. (1)
|
||||
|
||||
|
|
@ -2383,7 +2383,7 @@ fn package_only_prereleases_in_range() {
|
|||
|
||||
----- stderr -----
|
||||
× No solution found when resolving dependencies:
|
||||
╰─▶ Because only package-a<0.1.0 is available and you require package-a>0.1.0, we can conclude that your requirements are unsatisfiable.
|
||||
╰─▶ Because only package-a<=0.1.0 is available and you require package-a>0.1.0, we can conclude that your requirements are unsatisfiable.
|
||||
|
||||
hint: Pre-releases are available for `package-a` in the requested range (e.g., 1.0.0a1), but pre-releases weren't enabled (try: `--prerelease=allow`)
|
||||
");
|
||||
|
|
@ -2872,7 +2872,7 @@ fn transitive_package_only_prereleases_in_range() {
|
|||
|
||||
----- stderr -----
|
||||
× No solution found when resolving dependencies:
|
||||
╰─▶ Because only package-b<0.1 is available and package-a==0.1.0 depends on package-b>0.1, we can conclude that package-a==0.1.0 cannot be used.
|
||||
╰─▶ Because only package-b<=0.1 is available and package-a==0.1.0 depends on package-b>0.1, we can conclude that package-a==0.1.0 cannot be used.
|
||||
And because only package-a==0.1.0 is available and you require package-a, we can conclude that your requirements are unsatisfiable.
|
||||
|
||||
hint: Pre-releases are available for `package-b` in the requested range (e.g., 1.0.0a1), but pre-releases weren't enabled (try: `--prerelease=allow`)
|
||||
|
|
@ -2996,7 +2996,7 @@ fn transitive_prerelease_and_stable_dependency_many_versions_holes() {
|
|||
----- stderr -----
|
||||
× No solution found when resolving dependencies:
|
||||
╰─▶ Because only the following versions of package-c are available:
|
||||
package-c<1.0.0
|
||||
package-c<=1.0.0
|
||||
package-c>=2.0.0a5,<=2.0.0a7
|
||||
package-c==2.0.0b1
|
||||
package-c>=2.0.0b5
|
||||
|
|
@ -3980,7 +3980,7 @@ fn package_only_yanked_in_range() {
|
|||
----- stderr -----
|
||||
× No solution found when resolving dependencies:
|
||||
╰─▶ Because only the following versions of package-a are available:
|
||||
package-a<0.1.0
|
||||
package-a<=0.1.0
|
||||
package-a==1.0.0
|
||||
and package-a==1.0.0 was yanked (reason: Yanked for testing), we can conclude that package-a>0.1.0 cannot be used.
|
||||
And because you require package-a>0.1.0, we can conclude that your requirements are unsatisfiable.
|
||||
|
|
@ -4195,7 +4195,7 @@ fn transitive_package_only_yanked_in_range() {
|
|||
----- stderr -----
|
||||
× No solution found when resolving dependencies:
|
||||
╰─▶ Because only the following versions of package-b are available:
|
||||
package-b<0.1
|
||||
package-b<=0.1
|
||||
package-b==1.0.0
|
||||
and package-b==1.0.0 was yanked (reason: Yanked for testing), we can conclude that package-b>0.1 cannot be used.
|
||||
And because package-a==0.1.0 depends on package-b>0.1, we can conclude that package-a==0.1.0 cannot be used.
|
||||
|
|
|
|||
Loading…
Reference in New Issue