Skip to content

Commit 19f5985

Browse files
committed
Fix error message for pyemscripten abi incompatibility
1 parent e802a7c commit 19f5985

3 files changed

Lines changed: 77 additions & 17 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
66

77
## Unreleased
88

9+
### Fixed
10+
11+
- Incompatibility errors for `pyemscripten_*` / `pyodide_*` (PEP 783) platform
12+
wheels now report a meaningful Pyodide ABI version mismatch instead of a
13+
garbled message such as `Wheel was built with Emscripten vpyemscripten.2026.0`.
14+
915
### Changed
1016

1117
- `install` now raises a helpful `ValueError` when given a VCS URL

micropip/_utils.py

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -171,26 +171,55 @@ def check_compatible(filename: str) -> None:
171171
raise ValueError(f"Wheel version is invalid: {filename!r}") from None
172172

173173
tag: Tag = next(iter(tags))
174-
if "emscripten" not in tag.platform:
175-
raise ValueError(
176-
f"Wheel platform '{tag.platform}' is not compatible with "
177-
f"Pyodide's platform '{get_platform()}'"
178-
)
174+
platform = tag.platform
175+
176+
# PEP 783 Pyodide ABI platform tags, e.g. ``pyemscripten_2026_0_wasm32`` or
177+
# ``pyodide_2026_0_wasm32``. These encode the Pyodide ABI version rather than
178+
# the underlying Emscripten version, so they must be compared against the
179+
# runtime's ABI version, not its Emscripten version.
180+
pyodide_abi_prefixes = ("pyemscripten_", "pyodide_")
181+
if platform.startswith(pyodide_abi_prefixes):
182+
183+
def platform_to_abi_version(platform: str) -> str:
184+
for prefix in pyodide_abi_prefixes:
185+
platform = platform.removeprefix(prefix)
186+
return platform.removesuffix("_wasm32").replace("_", ".")
187+
188+
wheel_abi_version = platform_to_abi_version(platform)
189+
runtime_abi_version = get_config_var(
190+
"PYEMSCRIPTEN_PLATFORM_VERSION"
191+
) or get_config_var("PYODIDE_ABI_VERSION")
192+
if runtime_abi_version:
193+
runtime_abi_version = runtime_abi_version.replace("_", ".")
194+
if wheel_abi_version != runtime_abi_version:
195+
raise ValueError(
196+
f"Wheel was built with Pyodide ABI version {wheel_abi_version} but "
197+
f"the current environment has Pyodide ABI version "
198+
f"{runtime_abi_version}"
199+
)
179200

180-
def platform_to_version(platform: str) -> str:
181-
return (
182-
platform.replace("-", "_")
183-
.removeprefix("emscripten_")
184-
.removesuffix("_wasm32")
185-
.replace("_", ".")
186-
)
201+
elif "emscripten" in platform:
187202

188-
wheel_emscripten_version = platform_to_version(tag.platform)
189-
pyodide_emscripten_version = platform_to_version(get_platform())
190-
if wheel_emscripten_version != pyodide_emscripten_version:
203+
def platform_to_version(platform: str) -> str:
204+
return (
205+
platform.replace("-", "_")
206+
.removeprefix("emscripten_")
207+
.removesuffix("_wasm32")
208+
.replace("_", ".")
209+
)
210+
211+
wheel_emscripten_version = platform_to_version(platform)
212+
pyodide_emscripten_version = platform_to_version(get_platform())
213+
if wheel_emscripten_version != pyodide_emscripten_version:
214+
raise ValueError(
215+
f"Wheel was built with Emscripten v{wheel_emscripten_version} but "
216+
f"Pyodide was built with Emscripten v{pyodide_emscripten_version}"
217+
)
218+
219+
else:
191220
raise ValueError(
192-
f"Wheel was built with Emscripten v{wheel_emscripten_version} but "
193-
f"Pyodide was built with Emscripten v{pyodide_emscripten_version}"
221+
f"Wheel platform '{platform}' is not compatible with "
222+
f"Pyodide's platform '{get_platform()}'"
194223
)
195224

196225
abi_incompatible = True

tests/test_utils.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,31 @@ def test_check_compatible_wasm32(selenium_standalone_micropip):
118118
check_compatible(wheel_name)
119119

120120

121+
@pytest.mark.parametrize("prefix", ["pyemscripten", "pyodide"])
122+
def test_check_compatible_abi_version_mismatch(monkeypatch, prefix):
123+
"""
124+
A wheel built for a different Pyodide ABI version should report the ABI
125+
version mismatch instead of garbling it into an Emscripten version.
126+
"""
127+
import micropip._utils as _utils
128+
from micropip._utils import check_compatible
129+
130+
monkeypatch.setattr(
131+
_utils,
132+
"get_config_var",
133+
lambda name: "2026_0"
134+
if name in ("PYEMSCRIPTEN_PLATFORM_VERSION", "PYODIDE_ABI_VERSION")
135+
else None,
136+
)
137+
138+
wheel_name = f"pkg-1.0.0-{CPVER}-{CPVER}-{prefix}_2025_0_wasm32.whl"
139+
with raiseValueError(
140+
"Wheel was built with Pyodide ABI version 2025.0 but the current "
141+
"environment has Pyodide ABI version 2026.0"
142+
):
143+
check_compatible(wheel_name)
144+
145+
121146
_best_tag_test_cases = (
122147
"package, version, incompatible_tags, compatible_tags",
123148
# Tests assume that `compatible_tags` is sorted from least to most compatible:

0 commit comments

Comments
 (0)