From 82708944a36b97860b6574fd3d754d1b6e2d2e80 Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Wed, 9 Oct 2024 19:17:20 -0500 Subject: [PATCH] Fix `uv python pin 3.13t` failure when parsing version for project requires check (#8056) Closes https://github.com/astral-sh/uv/issues/7964 We can probably do some restructuring to avoid unwrapping here in the future, but this just fixes the bug quick. --- crates/uv-python/src/discovery.rs | 23 +++++++++++++++++++++++ crates/uv/src/commands/python/pin.rs | 8 ++++++-- crates/uv/tests/python_pin.rs | 16 ++++++++++++++-- 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/crates/uv-python/src/discovery.rs b/crates/uv-python/src/discovery.rs index 355b64b85f5c..8b237aecd1a4 100644 --- a/crates/uv-python/src/discovery.rs +++ b/crates/uv-python/src/discovery.rs @@ -1952,6 +1952,29 @@ impl VersionRequest { | Self::Range(_, variant) => variant == &PythonVariant::Freethreaded, } } + + /// Return a new [`VersionRequest`] with the [`PythonVariant`] if it has one. + /// + /// This is useful for converting the string representation to pep440. + #[must_use] + pub fn without_python_variant(self) -> Self { + // TODO(zanieb): Replace this entire function with a utility that casts this to a version + // without using `VersionRequest::to_string`. + match self { + Self::Any | Self::Default => self, + Self::Major(major, _) => Self::Major(major, PythonVariant::Default), + Self::MajorMinor(major, minor, _) => { + Self::MajorMinor(major, minor, PythonVariant::Default) + } + Self::MajorMinorPatch(major, minor, patch, _) => { + Self::MajorMinorPatch(major, minor, patch, PythonVariant::Default) + } + Self::MajorMinorPrerelease(major, minor, prerelease, _) => { + Self::MajorMinorPrerelease(major, minor, prerelease, PythonVariant::Default) + } + Self::Range(specifiers, _) => Self::Range(specifiers, PythonVariant::Default), + } + } } impl FromStr for VersionRequest { diff --git a/crates/uv/src/commands/python/pin.rs b/crates/uv/src/commands/python/pin.rs index 2e03dd5e5c12..653142c7516a 100644 --- a/crates/uv/src/commands/python/pin.rs +++ b/crates/uv/src/commands/python/pin.rs @@ -169,8 +169,12 @@ fn pep440_version_from_request(request: &PythonRequest) -> Option anyhow::Result<()> { - let context: TestContext = TestContext::new_with_versions(&["3.10", "3.11"]); + let context: TestContext = + TestContext::new_with_versions(&["3.10", "3.11"]).with_filtered_python_sources(); let pyproject_toml = context.temp_dir.child("pyproject.toml"); pyproject_toml.write_str( r#" @@ -294,12 +295,23 @@ fn python_pin_compatible_with_requires_python() -> anyhow::Result<()> { ----- stderr ----- "###); + // Request a version that is compatible and uses a Python variant + uv_snapshot!(context.filters(), context.python_pin().arg("3.13t"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + Updated `.python-version` from `3.11` -> `3.13t` + + ----- stderr ----- + warning: No interpreter found for Python 3.13t in [PYTHON SOURCES] + "###); + // Request a implementation version that is compatible uv_snapshot!(context.filters(), context.python_pin().arg("cpython@3.11"), @r###" success: true exit_code: 0 ----- stdout ----- - Updated `.python-version` from `3.11` -> `cpython@3.11` + Updated `.python-version` from `3.13t` -> `cpython@3.11` ----- stderr ----- "###);