Show expected and available ABI tags in resolver errors (#10527)

## Summary

The idea here is to show both (1) an example of a compatible tag and (2)
the tags that were available, whenever we fail to resolve due to an
abscence of matching wheels.

Closes https://github.com/astral-sh/uv/issues/2777.
This commit is contained in:
Charlie Marsh
2025-01-13 20:03:11 -05:00
committed by GitHub
parent e0e8ba582a
commit 2ffa31946d
13 changed files with 509 additions and 66 deletions
+18
View File
@@ -7,6 +7,7 @@ use pubgrub::Range;
use uv_distribution_filename::WheelFilename;
use uv_pep440::{release_specifiers_to_ranges, Version, VersionSpecifier, VersionSpecifiers};
use uv_pep508::{MarkerExpression, MarkerTree, MarkerValueVersion};
use uv_platform_tags::AbiTag;
/// The `Requires-Python` requirement specifier.
///
@@ -303,6 +304,23 @@ impl RequiresPython {
&self.range
}
/// Returns a wheel tag that's compatible with the `Requires-Python` specifier.
pub fn abi_tag(&self) -> Option<AbiTag> {
match self.range.lower().as_ref() {
Bound::Included(version) | Bound::Excluded(version) => {
let major = version.release().first().copied()?;
let major = u8::try_from(major).ok()?;
let minor = version.release().get(1).copied()?;
let minor = u8::try_from(minor).ok()?;
Some(AbiTag::CPython {
gil_disabled: false,
python_version: (major, minor),
})
}
Bound::Unbounded => None,
}
}
/// Simplifies the given markers in such a way as to assume that
/// the Python version is constrained by this Python version bound.
///