diff --git a/crates/uv-pep440/src/version.rs b/crates/uv-pep440/src/version.rs index 1b54909b9..46bea1aea 100644 --- a/crates/uv-pep440/src/version.rs +++ b/crates/uv-pep440/src/version.rs @@ -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. diff --git a/crates/uv-resolver/src/python_requirement.rs b/crates/uv-resolver/src/python_requirement.rs index 4b933843f..018525320 100644 --- a/crates/uv-resolver/src/python_requirement.rs +++ b/crates/uv-resolver/src/python_requirement.rs @@ -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), diff --git a/crates/uv/tests/it/pip_compile.rs b/crates/uv/tests/it/pip_compile.rs index a5bb819b2..864971b68 100644 --- a/crates/uv/tests/it/pip_compile.rs +++ b/crates/uv/tests/it/pip_compile.rs @@ -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(()) diff --git a/crates/uv/tests/it/pip_compile_scenarios.rs b/crates/uv/tests/it/pip_compile_scenarios.rs index 8e5a12401..1b1a0ca1d 100644 --- a/crates/uv/tests/it/pip_compile_scenarios.rs +++ b/crates/uv/tests/it/pip_compile_scenarios.rs @@ -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. "### );