diff --git a/crates/uv-platform-tags/src/abi_tag.rs b/crates/uv-platform-tags/src/abi_tag.rs index 2ea5c872e..70b11d8c2 100644 --- a/crates/uv-platform-tags/src/abi_tag.rs +++ b/crates/uv-platform-tags/src/abi_tag.rs @@ -34,7 +34,7 @@ pub enum AbiTag { python_version: Option<(u8, u8)>, implementation_version: (u8, u8), }, - /// Ex) `graalpy310_graalpy240_310_native` + /// Ex) `graalpy240_310_native` GraalPy { python_version: (u8, u8), implementation_version: (u8, u8), @@ -109,7 +109,7 @@ impl std::fmt::Display for AbiTag { } => { write!( f, - "graalpy{py_major}{py_minor}_graalpy{impl_major}{impl_minor}_{py_major}{py_minor}_native" + "graalpy{impl_major}{impl_minor}_{py_major}{py_minor}_native" ) } Self::Pyston { @@ -237,29 +237,21 @@ impl FromStr for AbiTag { }) } } else if let Some(rest) = s.strip_prefix("graalpy") { - // Ex) `graalpy310_graalpy240_310_native` - let version_end = rest - .find('_') - .ok_or_else(|| ParseAbiTagError::InvalidFormat { - implementation: "GraalPy", - tag: s.to_string(), - })?; - let version_str = &rest[..version_end]; - let (major, minor) = parse_python_version(version_str, "GraalPy", s)?; - let rest = rest[version_end + 1..] - .strip_prefix("graalpy") - .ok_or_else(|| ParseAbiTagError::InvalidFormat { - implementation: "GraalPy", - tag: s.to_string(), - })?; - let version_end = rest - .find('_') - .ok_or_else(|| ParseAbiTagError::InvalidFormat { - implementation: "GraalPy", - tag: s.to_string(), - })?; - let rest = &rest[..version_end]; - let (impl_major, impl_minor) = parse_impl_version(rest, "GraalPy", s)?; + // Ex) `graalpy240_310_native` + let (impl_ver_str, rest) = + rest.split_once('_') + .ok_or_else(|| ParseAbiTagError::InvalidFormat { + implementation: "GraalPy", + tag: s.to_string(), + })?; + let (impl_major, impl_minor) = parse_impl_version(impl_ver_str, "GraalPy", s)?; + let (py_ver_str, _) = + rest.split_once('_') + .ok_or_else(|| ParseAbiTagError::InvalidFormat { + implementation: "GraalPy", + tag: s.to_string(), + })?; + let (major, minor) = parse_python_version(py_ver_str, "GraalPy", s)?; Ok(Self::GraalPy { python_version: (major, minor), implementation_version: (impl_major, impl_minor), @@ -434,11 +426,8 @@ mod tests { python_version: (3, 10), implementation_version: (2, 40), }; - assert_eq!( - AbiTag::from_str("graalpy310_graalpy240_310_native"), - Ok(tag) - ); - assert_eq!(tag.to_string(), "graalpy310_graalpy240_310_native"); + assert_eq!(AbiTag::from_str("graalpy240_310_native"), Ok(tag)); + assert_eq!(tag.to_string(), "graalpy240_310_native"); assert_eq!( AbiTag::from_str("graalpy310"), diff --git a/crates/uv-platform-tags/src/tags.rs b/crates/uv-platform-tags/src/tags.rs index 2a85a3114..22ad12dbf 100644 --- a/crates/uv-platform-tags/src/tags.rs +++ b/crates/uv-platform-tags/src/tags.rs @@ -395,7 +395,7 @@ impl Implementation { python_version: Some(python_version), implementation_version, }, - // Ex) `graalpy310_graalpy240_310_native + // Ex) `graalpy240_310_native Self::GraalPy => AbiTag::GraalPy { python_version, implementation_version, diff --git a/crates/uv-python/python/get_interpreter_info.py b/crates/uv-python/python/get_interpreter_info.py index c134a0a6b..2b1ee09cc 100644 --- a/crates/uv-python/python/get_interpreter_info.py +++ b/crates/uv-python/python/get_interpreter_info.py @@ -34,8 +34,18 @@ if sys.version_info[0] < 3: sys.exit(0) if hasattr(sys, "implementation"): - implementation_version = format_full_version(sys.implementation.version) implementation_name = sys.implementation.name + if implementation_name == "graalpy": + # GraalPy reports the CPython version as sys.implementation.version, + # so we need to discover the GraalPy version from the cache_tag + import re + implementation_version = re.sub( + r"graalpy(\d)(\d+)-\d+", + r"\1.\2", + sys.implementation.cache_tag + ) + else: + implementation_version = format_full_version(sys.implementation.version) else: implementation_version = "0" implementation_name = "" diff --git a/crates/uv/tests/it/common/mod.rs b/crates/uv/tests/it/common/mod.rs index 6ff533cad..f7b0a0b62 100644 --- a/crates/uv/tests/it/common/mod.rs +++ b/crates/uv/tests/it/common/mod.rs @@ -32,7 +32,7 @@ use uv_static::EnvVars; // Exclude any packages uploaded after this date. static EXCLUDE_NEWER: &str = "2024-03-25T00:00:00Z"; -pub const PACKSE_VERSION: &str = "0.3.45"; +pub const PACKSE_VERSION: &str = "0.3.46"; /// Using a find links url allows using `--index-url` instead of `--extra-index-url` in tests /// to prevent dependency confusion attacks against our test suite. diff --git a/crates/uv/tests/it/pip_install_scenarios.rs b/crates/uv/tests/it/pip_install_scenarios.rs index fa422c466..41008cdb4 100644 --- a/crates/uv/tests/it/pip_install_scenarios.rs +++ b/crates/uv/tests/it/pip_install_scenarios.rs @@ -4091,7 +4091,7 @@ fn no_sdist_no_wheels_with_matching_abi() { ╰─▶ Because only package-a==1.0.0 is available and package-a==1.0.0 has no wheels with a matching Python ABI tag (e.g., `cp38`), we can conclude that all versions of package-a cannot be used. And because you require package-a, we can conclude that your requirements are unsatisfiable. - hint: You require CPython 3.8 (`cp38`), but we only found wheels for `package-a` (v1.0.0) with the following Python ABI tag: `graalpy310_graalpy240_310_native` + hint: You require CPython 3.8 (`cp38`), but we only found wheels for `package-a` (v1.0.0) with the following Python ABI tag: `graalpy240_310_native` "###); assert_not_installed(