mirror of
https://github.com/astral-sh/uv.git
synced 2025-10-28 18:54:10 +00:00
Simplify available package version ranges when the name includes markers or extras (#6162)
There were different `PubGrubPackage` types so they never matched the available versions set! Luckily, the available versions are agnostic to the markers and optional dependencies so we can just broaden to using `PackageName` as a lookup key. Addresses yet another complaint in https://github.com/astral-sh/uv/issues/5046
This commit is contained in:
parent
05cceee523
commit
ea636bbe61
5 changed files with 24 additions and 46 deletions
|
|
@ -120,7 +120,7 @@ pub(crate) type ErrorTree = DerivationTree<PubGrubPackage, Range<Version>, Unava
|
|||
#[derive(Debug)]
|
||||
pub struct NoSolutionError {
|
||||
error: pubgrub::NoSolutionError<UvDependencyProvider>,
|
||||
available_versions: FxHashMap<PubGrubPackage, BTreeSet<Version>>,
|
||||
available_versions: FxHashMap<PackageName, BTreeSet<Version>>,
|
||||
selector: CandidateSelector,
|
||||
python_requirement: PythonRequirement,
|
||||
index_locations: IndexLocations,
|
||||
|
|
@ -135,7 +135,7 @@ impl NoSolutionError {
|
|||
/// Create a new [`NoSolutionError`] from a [`pubgrub::NoSolutionError`].
|
||||
pub(crate) fn new(
|
||||
error: pubgrub::NoSolutionError<UvDependencyProvider>,
|
||||
available_versions: FxHashMap<PubGrubPackage, BTreeSet<Version>>,
|
||||
available_versions: FxHashMap<PackageName, BTreeSet<Version>>,
|
||||
selector: CandidateSelector,
|
||||
python_requirement: PythonRequirement,
|
||||
index_locations: IndexLocations,
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ use super::{PubGrubPackage, PubGrubPackageInner, PubGrubPython};
|
|||
#[derive(Debug)]
|
||||
pub(crate) struct PubGrubReportFormatter<'a> {
|
||||
/// The versions that were available for each package
|
||||
pub(crate) available_versions: &'a FxHashMap<PubGrubPackage, BTreeSet<Version>>,
|
||||
pub(crate) available_versions: &'a FxHashMap<PackageName, BTreeSet<Version>>,
|
||||
|
||||
/// The versions that were available for each package
|
||||
pub(crate) python_requirement: &'a PythonRequirement,
|
||||
|
|
@ -87,7 +87,7 @@ impl ReportFormatter<PubGrubPackage, Range<Version>, UnavailableReason>
|
|||
// Note that sometimes we do not have a range of available versions, e.g.,
|
||||
// when a package is from a non-registry source. In that case, we cannot
|
||||
// perform further simplicifaction of the range.
|
||||
if let Some(available_versions) = self.available_versions.get(package) {
|
||||
if let Some(available_versions) = package.name().and_then(|name| self.available_versions.get(name)) {
|
||||
update_availability_range(&complement, available_versions)
|
||||
} else {
|
||||
complement
|
||||
|
|
@ -484,10 +484,13 @@ impl PubGrubReportFormatter<'_> {
|
|||
set: &'a Range<Version>,
|
||||
package: &PubGrubPackage,
|
||||
) -> Cow<'a, Range<Version>> {
|
||||
let Some(name) = package.name() else {
|
||||
return Cow::Borrowed(set);
|
||||
};
|
||||
if set == &Range::full() {
|
||||
Cow::Borrowed(set)
|
||||
} else {
|
||||
Cow::Owned(set.simplify(self.available_versions.get(package).into_iter().flatten()))
|
||||
Cow::Owned(set.simplify(self.available_versions.get(name).into_iter().flatten()))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -695,13 +698,17 @@ impl PubGrubReportFormatter<'_> {
|
|||
range: self.simplify_set(set, package).into_owned(),
|
||||
});
|
||||
}
|
||||
} else if let Some(version) = self.available_versions.get(package).and_then(|versions| {
|
||||
versions
|
||||
.iter()
|
||||
.rev()
|
||||
.filter(|version| version.any_prerelease())
|
||||
.find(|version| set.contains(version))
|
||||
}) {
|
||||
} else if let Some(version) = package
|
||||
.name()
|
||||
.and_then(|name| self.available_versions.get(name))
|
||||
.and_then(|versions| {
|
||||
versions
|
||||
.iter()
|
||||
.rev()
|
||||
.filter(|version| version.any_prerelease())
|
||||
.find(|version| set.contains(version))
|
||||
})
|
||||
{
|
||||
// There are pre-release versions available for the package.
|
||||
if selector.prerelease_strategy().allows(name, markers) != AllowPrerelease::Yes {
|
||||
hints.insert(PubGrubHint::PrereleaseAvailable {
|
||||
|
|
|
|||
|
|
@ -1963,9 +1963,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
|||
|
||||
let mut available_versions = FxHashMap::default();
|
||||
for package in err.packages() {
|
||||
let PubGrubPackageInner::Package { name, .. } = &**package else {
|
||||
continue;
|
||||
};
|
||||
let Some(name) = package.name() else { continue };
|
||||
if !visited.contains(name) {
|
||||
// Avoid including available versions for packages that exist in the derivation
|
||||
// tree, but were never visited during resolution. We _may_ have metadata for
|
||||
|
|
@ -1977,7 +1975,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
|||
if let VersionsResponse::Found(ref version_maps) = *response {
|
||||
for version_map in version_maps {
|
||||
available_versions
|
||||
.entry(package.clone())
|
||||
.entry(name.clone())
|
||||
.or_insert_with(BTreeSet::new)
|
||||
.extend(version_map.iter().map(|(version, _)| version.clone()));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -433,7 +433,7 @@ fn conflict_in_fork() -> Result<()> {
|
|||
And because package-a{sys_platform == 'darwin'}==1.0.0 depends on package-b and package-c, we can conclude that package-a{sys_platform == 'darwin'}==1.0.0 cannot be used.
|
||||
And because only the following versions of package-a{sys_platform == 'darwin'} are available:
|
||||
package-a{sys_platform == 'darwin'}==1.0.0
|
||||
package-a{sys_platform == 'darwin'}>=2
|
||||
package-a{sys_platform == 'darwin'}>2
|
||||
and your project depends on package-a{sys_platform == 'darwin'}<2, we can conclude that your project's requirements are unsatisfiable.
|
||||
"###
|
||||
);
|
||||
|
|
@ -2875,7 +2875,7 @@ fn fork_non_local_fork_marker_transitive() -> Result<()> {
|
|||
╰─▶ Because package-b==1.0.0 depends on package-c{sys_platform == 'darwin'}>=2.0.0 and only package-c{sys_platform == 'darwin'}<=2.0.0 is available, we can conclude that package-b==1.0.0 depends on package-c{sys_platform == 'darwin'}==2.0.0.
|
||||
And because only the following versions of package-c{sys_platform == 'linux'} are available:
|
||||
package-c{sys_platform == 'linux'}==1.0.0
|
||||
package-c{sys_platform == 'linux'}>=2.0.0
|
||||
package-c{sys_platform == 'linux'}>2.0.0
|
||||
and package-a==1.0.0 depends on package-c{sys_platform == 'linux'}<2.0.0, we can conclude that package-a==1.0.0 and package-b==1.0.0 are incompatible.
|
||||
And because your project depends on package-a==1.0.0 and package-b==1.0.0, we can conclude that your project's requirements are unsatisfiable.
|
||||
"###
|
||||
|
|
|
|||
|
|
@ -7993,34 +7993,7 @@ fn universal_requires_python_incomplete() -> Result<()> {
|
|||
----- stderr -----
|
||||
warning: The requested Python version 3.7 is not available; 3.12.[X] will be used to build dependencies instead.
|
||||
× No solution found when resolving dependencies:
|
||||
╰─▶ Because only the following versions of uv{python_full_version >= '3.8'} are available:
|
||||
uv{python_full_version >= '3.8'}==0.0.5
|
||||
uv{python_full_version >= '3.8'}==0.1.0
|
||||
uv{python_full_version >= '3.8'}==0.1.1
|
||||
uv{python_full_version >= '3.8'}==0.1.2
|
||||
uv{python_full_version >= '3.8'}==0.1.3
|
||||
uv{python_full_version >= '3.8'}==0.1.4
|
||||
uv{python_full_version >= '3.8'}==0.1.5
|
||||
uv{python_full_version >= '3.8'}==0.1.6
|
||||
uv{python_full_version >= '3.8'}==0.1.7
|
||||
uv{python_full_version >= '3.8'}==0.1.8
|
||||
uv{python_full_version >= '3.8'}==0.1.9
|
||||
uv{python_full_version >= '3.8'}==0.1.10
|
||||
uv{python_full_version >= '3.8'}==0.1.11
|
||||
uv{python_full_version >= '3.8'}==0.1.12
|
||||
uv{python_full_version >= '3.8'}==0.1.13
|
||||
uv{python_full_version >= '3.8'}==0.1.14
|
||||
uv{python_full_version >= '3.8'}==0.1.15
|
||||
uv{python_full_version >= '3.8'}==0.1.16
|
||||
uv{python_full_version >= '3.8'}==0.1.17
|
||||
uv{python_full_version >= '3.8'}==0.1.18
|
||||
uv{python_full_version >= '3.8'}==0.1.19
|
||||
uv{python_full_version >= '3.8'}==0.1.20
|
||||
uv{python_full_version >= '3.8'}==0.1.21
|
||||
uv{python_full_version >= '3.8'}==0.1.22
|
||||
uv{python_full_version >= '3.8'}==0.1.23
|
||||
uv{python_full_version >= '3.8'}==0.1.24
|
||||
and the requested Python version (>=3.7) does not satisfy Python>=3.8, we can conclude that all versions of uv{python_full_version >= '3.8'} are incompatible.
|
||||
╰─▶ Because only uv{python_full_version >= '3.8'}<=0.1.24 is available and the requested Python version (>=3.7) does not satisfy Python>=3.8, we can conclude that all versions of uv{python_full_version >= '3.8'} are incompatible.
|
||||
And because you require uv{python_full_version >= '3.8'}, we can conclude that your requirements are unsatisfiable.
|
||||
"###
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue