Add support for pypy_73-style tags (#10660)

## Summary

I'm inferring that these are like... the older tag format? See, e.g.:

```
soxbindings-0.0.1-pp27-pypy_73-macosx_10_9_x86_64.whl
soxbindings-0.0.1-pp27-pypy_73-manylinux2010_x86_64.whl
soxbindings-0.0.1-pp36-pypy36_pp73-macosx_10_9_x86_64.whl
soxbindings-0.0.1-pp36-pypy36_pp73-manylinux2010_x86_64.whl
```
This commit is contained in:
Charlie Marsh 2025-01-15 18:27:17 -05:00 committed by GitHub
parent 1c17662b37
commit ee6ba41d46
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 61 additions and 31 deletions

View file

@ -32,7 +32,7 @@ pub enum AbiTag {
}, },
/// Ex) `pypy39_pp73` /// Ex) `pypy39_pp73`
PyPy { PyPy {
python_version: (u8, u8), python_version: Option<(u8, u8)>,
implementation_version: (u8, u8), implementation_version: (u8, u8),
}, },
/// Ex) `graalpy310_graalpy240_310_native` /// Ex) `graalpy310_graalpy240_310_native`
@ -55,12 +55,20 @@ impl AbiTag {
AbiTag::CPython { python_version, .. } => { AbiTag::CPython { python_version, .. } => {
Some(format!("CPython {}.{}", python_version.0, python_version.1)) Some(format!("CPython {}.{}", python_version.0, python_version.1))
} }
AbiTag::PyPy { python_version, .. } => { AbiTag::PyPy {
Some(format!("PyPy {}.{}", python_version.0, python_version.1)) implementation_version,
} ..
AbiTag::GraalPy { python_version, .. } => { } => Some(format!(
Some(format!("GraalPy {}.{}", python_version.0, python_version.1)) "PyPy {}.{}",
} implementation_version.0, implementation_version.1
)),
AbiTag::GraalPy {
implementation_version,
..
} => Some(format!(
"GraalPy {}.{}",
implementation_version.0, implementation_version.1
)),
AbiTag::Pyston { .. } => Some("Pyston".to_string()), AbiTag::Pyston { .. } => Some("Pyston".to_string()),
AbiTag::Unknown { .. } => None, AbiTag::Unknown { .. } => None,
} }
@ -88,11 +96,17 @@ impl std::fmt::Display for AbiTag {
} }
} }
Self::PyPy { Self::PyPy {
python_version: (py_major, py_minor), python_version: Some((py_major, py_minor)),
implementation_version: (impl_major, impl_minor), implementation_version: (impl_major, impl_minor),
} => { } => {
write!(f, "pypy{py_major}{py_minor}_pp{impl_major}{impl_minor}") write!(f, "pypy{py_major}{py_minor}_pp{impl_major}{impl_minor}")
} }
Self::PyPy {
python_version: None,
implementation_version: (impl_major, impl_minor),
} => {
write!(f, "pypy_{impl_major}{impl_minor}")
}
Self::GraalPy { Self::GraalPy {
python_version: (py_major, py_minor), python_version: (py_major, py_minor),
implementation_version: (impl_major, impl_minor), implementation_version: (impl_major, impl_minor),
@ -196,25 +210,34 @@ impl AbiTag {
python_version: (major, minor), python_version: (major, minor),
}) })
} else if let Some(rest) = s.strip_prefix("pypy") { } else if let Some(rest) = s.strip_prefix("pypy") {
// Ex) `pypy39_pp73` if let Some(rest) = rest.strip_prefix('_') {
let (version_str, rest) = // Ex) `pypy_73`
rest.split_once('_') let (impl_major, impl_minor) = parse_impl_version(rest, "PyPy", s)?;
.ok_or_else(|| ParseAbiTagError::InvalidFormat { Ok(Self::PyPy {
implementation: "PyPy", python_version: None,
tag: s.to_string(), implementation_version: (impl_major, impl_minor),
})?; })
let (major, minor) = parse_python_version(version_str, "PyPy", s)?; } else {
let rest = rest // Ex) `pypy39_pp73`
.strip_prefix("pp") let (version_str, rest) =
.ok_or_else(|| ParseAbiTagError::InvalidFormat { rest.split_once('_')
implementation: "PyPy", .ok_or_else(|| ParseAbiTagError::InvalidFormat {
tag: s.to_string(), implementation: "PyPy",
})?; tag: s.to_string(),
let (impl_major, impl_minor) = parse_impl_version(rest, "PyPy", s)?; })?;
Ok(Self::PyPy { let (major, minor) = parse_python_version(version_str, "PyPy", s)?;
python_version: (major, minor), let rest =
implementation_version: (impl_major, impl_minor), rest.strip_prefix("pp")
}) .ok_or_else(|| ParseAbiTagError::InvalidFormat {
implementation: "PyPy",
tag: s.to_string(),
})?;
let (impl_major, impl_minor) = parse_impl_version(rest, "PyPy", s)?;
Ok(Self::PyPy {
python_version: Some((major, minor)),
implementation_version: (impl_major, impl_minor),
})
}
} else if let Some(rest) = s.strip_prefix("graalpy") { } else if let Some(rest) = s.strip_prefix("graalpy") {
// Ex) `graalpy310_graalpy240_310_native` // Ex) `graalpy310_graalpy240_310_native`
let version_end = rest let version_end = rest
@ -377,12 +400,19 @@ mod tests {
#[test] #[test]
fn pypy_abi() { fn pypy_abi() {
let tag = AbiTag::PyPy { let tag = AbiTag::PyPy {
python_version: (3, 9), python_version: Some((3, 9)),
implementation_version: (7, 3), implementation_version: (7, 3),
}; };
assert_eq!(AbiTag::parse("pypy39_pp73").as_ref(), Ok(&tag)); assert_eq!(AbiTag::parse("pypy39_pp73").as_ref(), Ok(&tag));
assert_eq!(tag.to_string(), "pypy39_pp73"); assert_eq!(tag.to_string(), "pypy39_pp73");
let tag = AbiTag::PyPy {
python_version: None,
implementation_version: (7, 3),
};
assert_eq!(AbiTag::parse("pypy_73").as_ref(), Ok(&tag));
assert_eq!(tag.to_string(), "pypy_73");
assert_eq!( assert_eq!(
AbiTag::parse("pypy39"), AbiTag::parse("pypy39"),
Err(ParseAbiTagError::InvalidFormat { Err(ParseAbiTagError::InvalidFormat {

View file

@ -392,7 +392,7 @@ impl Implementation {
}, },
// Ex) `pypy39_pp73` // Ex) `pypy39_pp73`
Self::PyPy => AbiTag::PyPy { Self::PyPy => AbiTag::PyPy {
python_version, python_version: Some(python_version),
implementation_version, implementation_version,
}, },
// Ex) `graalpy310_graalpy240_310_native // Ex) `graalpy310_graalpy240_310_native

View file

@ -464,7 +464,7 @@ impl RequiresPython {
python_version: (2, ..), python_version: (2, ..),
.. ..
} | AbiTag::PyPy { } | AbiTag::PyPy {
python_version: (2, ..), python_version: None | Some((2, ..)),
.. ..
} | AbiTag::GraalPy { } | AbiTag::GraalPy {
python_version: (2, ..), python_version: (2, ..),
@ -478,7 +478,7 @@ impl RequiresPython {
.. ..
} }
| AbiTag::PyPy { | AbiTag::PyPy {
python_version: (3, minor), python_version: Some((3, minor)),
.. ..
} }
| AbiTag::GraalPy { | AbiTag::GraalPy {