mirror of
https://github.com/astral-sh/uv.git
synced 2025-11-03 05:03:46 +00:00
Omit trailing zeros on Python requirements inferred from versions (#9952)
In a message like
```
❯ echo "numpy>2" | uv pip compile -p 3.8 -
× No solution found when resolving dependencies:
╰─▶ Because the requested Python version (>=3.8.0) does not satisfy Python>=3.10 and the requested
Python version (>=3.8.0) does not satisfy Python>=3.9,<3.10, we can conclude that Python>=3.9 is incompatible.
And because numpy>=2.0.1,<=2.0.2 depends on Python>=3.9 and only the following versions of numpy are available:
numpy<=2.0.2
```
I'm surprised that `-p 3.8` leads to expressions like `>=3.8.0` (I
understand it, of course, but it's not intuitive) and then all the
_other_ Python versions in the message omit the trailing zero. This
updates the `PythonRequirement` parsing to drop the trailing zeros. It's
easier to do there because the version is not yet abstracted.
This commit is contained in:
parent
2288905d46
commit
a78e7468a7
4 changed files with 50 additions and 12 deletions
|
|
@ -580,6 +580,21 @@ impl Version {
|
|||
Self::new(self.release().iter().copied())
|
||||
}
|
||||
|
||||
/// Return the version with trailing `.0` release segments removed.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// When the release is all zero segments.
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn without_trailing_zeros(self) -> Self {
|
||||
let mut release = self.release().to_vec();
|
||||
while let Some(0) = release.last() {
|
||||
release.pop();
|
||||
}
|
||||
self.with_release(release)
|
||||
}
|
||||
|
||||
/// Set the min-release component and return the updated version.
|
||||
///
|
||||
/// The "min" component is internal-only, and does not exist in PEP 440.
|
||||
|
|
|
|||
|
|
@ -24,8 +24,15 @@ impl PythonRequirement {
|
|||
/// [`PythonVersion`].
|
||||
pub fn from_python_version(interpreter: &Interpreter, python_version: &PythonVersion) -> Self {
|
||||
let exact = interpreter.python_full_version().version.clone();
|
||||
let installed = interpreter.python_full_version().version.only_release();
|
||||
let target = python_version.python_full_version().only_release();
|
||||
let installed = interpreter
|
||||
.python_full_version()
|
||||
.version
|
||||
.only_release()
|
||||
.without_trailing_zeros();
|
||||
let target = python_version
|
||||
.python_full_version()
|
||||
.only_release()
|
||||
.without_trailing_zeros();
|
||||
Self {
|
||||
exact,
|
||||
installed: RequiresPython::greater_than_equal_version(&installed),
|
||||
|
|
@ -45,8 +52,16 @@ impl PythonRequirement {
|
|||
|
||||
/// Create a [`PythonRequirement`] to resolve against an [`Interpreter`].
|
||||
pub fn from_interpreter(interpreter: &Interpreter) -> Self {
|
||||
let exact = interpreter.python_full_version().version.clone();
|
||||
let installed = interpreter.python_full_version().version.only_release();
|
||||
let exact = interpreter
|
||||
.python_full_version()
|
||||
.version
|
||||
.clone()
|
||||
.without_trailing_zeros();
|
||||
let installed = interpreter
|
||||
.python_full_version()
|
||||
.version
|
||||
.only_release()
|
||||
.without_trailing_zeros();
|
||||
Self {
|
||||
exact,
|
||||
installed: RequiresPython::greater_than_equal_version(&installed),
|
||||
|
|
@ -65,8 +80,16 @@ impl PythonRequirement {
|
|||
marker_env: &MarkerEnvironment,
|
||||
requires_python: RequiresPython,
|
||||
) -> Self {
|
||||
let exact = marker_env.python_full_version().version.clone();
|
||||
let installed = marker_env.python_full_version().version.only_release();
|
||||
let exact = marker_env
|
||||
.python_full_version()
|
||||
.version
|
||||
.clone()
|
||||
.without_trailing_zeros();
|
||||
let installed = marker_env
|
||||
.python_full_version()
|
||||
.version
|
||||
.only_release()
|
||||
.without_trailing_zeros();
|
||||
Self {
|
||||
exact,
|
||||
installed: RequiresPython::greater_than_equal_version(&installed),
|
||||
|
|
|
|||
|
|
@ -1401,10 +1401,10 @@ fn compile_python_37() -> Result<()> {
|
|||
|
||||
----- stderr -----
|
||||
× No solution found when resolving dependencies:
|
||||
╰─▶ Because the requested Python version (>=3.7.0) does not satisfy Python>=3.8 and black==23.10.1 depends on Python>=3.8, we can conclude that black==23.10.1 cannot be used.
|
||||
╰─▶ Because the requested Python version (>=3.7) does not satisfy Python>=3.8 and black==23.10.1 depends on Python>=3.8, we can conclude that black==23.10.1 cannot be used.
|
||||
And because you require black==23.10.1, we can conclude that your requirements are unsatisfiable.
|
||||
|
||||
hint: The `--python-version` value (>=3.7.0) includes Python versions that are not supported by your dependencies (e.g., black==23.10.1 only supports >=3.8). Consider using a higher `--python-version` value.
|
||||
hint: The `--python-version` value (>=3.7) includes Python versions that are not supported by your dependencies (e.g., black==23.10.1 only supports >=3.8). Consider using a higher `--python-version` value.
|
||||
"###);
|
||||
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -75,10 +75,10 @@ fn compatible_python_incompatible_override() -> Result<()> {
|
|||
----- stderr -----
|
||||
warning: The requested Python version 3.9 is not available; 3.11.[X] will be used to build dependencies instead.
|
||||
× No solution found when resolving dependencies:
|
||||
╰─▶ Because the requested Python version (>=3.9.0) does not satisfy Python>=3.10 and package-a==1.0.0 depends on Python>=3.10, we can conclude that package-a==1.0.0 cannot be used.
|
||||
╰─▶ Because the requested Python version (>=3.9) does not satisfy Python>=3.10 and package-a==1.0.0 depends on Python>=3.10, we can conclude that package-a==1.0.0 cannot be used.
|
||||
And because you require package-a==1.0.0, we can conclude that your requirements are unsatisfiable.
|
||||
|
||||
hint: The `--python-version` value (>=3.9.0) includes Python versions that are not supported by your dependencies (e.g., package-a==1.0.0 only supports >=3.10). Consider using a higher `--python-version` value.
|
||||
hint: The `--python-version` value (>=3.9) includes Python versions that are not supported by your dependencies (e.g., package-a==1.0.0 only supports >=3.10). Consider using a higher `--python-version` value.
|
||||
"###
|
||||
);
|
||||
|
||||
|
|
@ -384,10 +384,10 @@ fn python_patch_override_no_patch() -> Result<()> {
|
|||
|
||||
----- stderr -----
|
||||
× No solution found when resolving dependencies:
|
||||
╰─▶ Because the requested Python version (>=3.8.0) does not satisfy Python>=3.8.4 and package-a==1.0.0 depends on Python>=3.8.4, we can conclude that package-a==1.0.0 cannot be used.
|
||||
╰─▶ Because the requested Python version (>=3.8) does not satisfy Python>=3.8.4 and package-a==1.0.0 depends on Python>=3.8.4, we can conclude that package-a==1.0.0 cannot be used.
|
||||
And because you require package-a==1.0.0, we can conclude that your requirements are unsatisfiable.
|
||||
|
||||
hint: The `--python-version` value (>=3.8.0) includes Python versions that are not supported by your dependencies (e.g., package-a==1.0.0 only supports >=3.8.4). Consider using a higher `--python-version` value.
|
||||
hint: The `--python-version` value (>=3.8) includes Python versions that are not supported by your dependencies (e.g., package-a==1.0.0 only supports >=3.8.4). Consider using a higher `--python-version` value.
|
||||
"###
|
||||
);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue