From 308dfae2efa3e9b874fda7fe21782653b3033dfa Mon Sep 17 00:00:00 2001 From: Feodor Fitsner Date: Mon, 1 Jun 2026 12:40:57 -0700 Subject: [PATCH] Preserve upstream wheel Python/ABI tag in fix_wheel (#61) fix_wheel was unconditionally rewriting the WHEEL Tag with `self.wheel_tag` (cp3X-cp3X-), discarding the tag maturin / the upstream backend had emitted. For abi3 crates like cryptography this turned `cp37-abi3-` into `cp312-cp312-` and the produced wheel name followed, which was wrong on three counts: - semantically incorrect: the inner _rust.abi3.so is stable-ABI; - unnecessarily restrictive: pip refuses the wheel on cp313+; - wasteful: forces per-Python-version rebuilds. Now `fix_wheel` keeps the existing pythontag-abitag portion and swaps only the platform component, falling back to self.wheel_tag only when the upstream wheel didn't carry a Tag header. Restores the cp3X-abi3-* wheels we shipped before commit 4cf1c1f. --- src/forge/build.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/forge/build.py b/src/forge/build.py index 1d12bf7..ef7da5c 100644 --- a/src/forge/build.py +++ b/src/forge/build.py @@ -649,11 +649,21 @@ def fix_wheel(self, wheel_dir: Path): # Normalize wheel tags to forge platform tags so repacked wheels use # android_24_arm64_v8a / ios_13_0_arm64_iphoneos style platform tags. + # Preserve the Python/ABI part the upstream build wrote (e.g. maturin + # emits `cp37-abi3-*` for cryptography); only the platform component + # is swapped. Falls back to self.wheel_tag when no Tag was written. wheel_metadata_path = next(wheel_dir.glob("*.dist-info")) / "WHEEL" wheel_metadata = self.read_message_file(wheel_metadata_path) - if "Tag" in wheel_metadata: - del wheel_metadata["Tag"] - wheel_metadata["Tag"] = self.wheel_tag + upstream_tags = wheel_metadata.get_all("Tag", []) + del wheel_metadata["Tag"] + new_tags = [] + for tag in upstream_tags: + py, abi, _platform = tag.rsplit("-", 2) + new_tags.append(f"{py}-{abi}-{self.cross_venv.tag}") + if not new_tags: + new_tags = [self.wheel_tag] + for tag in new_tags: + wheel_metadata["Tag"] = tag self.write_message_file(wheel_metadata_path, wheel_metadata) if self.cross_venv.sdk == "android":