Skip to content

Commit

Permalink
Fix uv python pin 3.13t failure when parsing version for project re…
Browse files Browse the repository at this point in the history
…quires check (#8056)

Closes #7964

We can probably do some restructuring to avoid unwrapping here in the
future, but this just fixes the bug quick.
  • Loading branch information
zanieb authored Oct 10, 2024
1 parent 46a0ed7 commit 8270894
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 4 deletions.
23 changes: 23 additions & 0 deletions crates/uv-python/src/discovery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
8 changes: 6 additions & 2 deletions crates/uv/src/commands/python/pin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,12 @@ fn pep440_version_from_request(request: &PythonRequest) -> Option<uv_pep440::Ver
return None;
}

// SAFETY: converting `VersionRequest` to `Version` is guaranteed to succeed if not a `Range`.
Some(uv_pep440::Version::from_str(&version_request.to_string()).unwrap())
// SAFETY: converting `VersionRequest` to `Version` is guaranteed to succeed if not a `Range`
// and does not have a Python variant (e.g., freethreaded) attached.
Some(
uv_pep440::Version::from_str(&version_request.clone().without_python_variant().to_string())
.unwrap(),
)
}

/// Check if pinned request is compatible with the workspace/project's `Requires-Python`.
Expand Down
16 changes: 14 additions & 2 deletions crates/uv/tests/python_pin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,8 @@ fn python_pin_no_python() {

#[test]
fn python_pin_compatible_with_requires_python() -> 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#"
Expand Down Expand Up @@ -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("[email protected]"), @r###"
success: true
exit_code: 0
----- stdout -----
Updated `.python-version` from `3.11` -> `[email protected]`
Updated `.python-version` from `3.13t` -> `[email protected]`
----- stderr -----
"###);
Expand Down

0 comments on commit 8270894

Please sign in to comment.