From 93ae5ea8676acbdb831891d2e343cf5cf176c26e Mon Sep 17 00:00:00 2001 From: Tianyi Cui <53024+tianyicui@users.noreply.github.com> Date: Thu, 30 Jul 2026 00:08:17 +0800 Subject: [PATCH] fix(python): name unsupported release executables --- python/sdk/tests/test_release_version.py | 21 +++++++++++++++++++++ scripts/build-python-release.py | 14 ++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/python/sdk/tests/test_release_version.py b/python/sdk/tests/test_release_version.py index fad1d01cda..ce54185ba5 100644 --- a/python/sdk/tests/test_release_version.py +++ b/python/sdk/tests/test_release_version.py @@ -85,6 +85,27 @@ def test_stage_runtime_rejects_missing_spawn_helper(tmp_path: Path) -> None: ) +def test_stage_runtime_rejects_unsupported_executable_name(tmp_path: Path) -> None: + executable = tmp_path / "custom-runtime" + executable.write_bytes(b"runtime") + executable.chmod(0o755) + + with pytest.raises( + ValueError, + match=( + "unsupported runtime executable 'custom-runtime'; expected one of: " + "dsh-jsonrpc-agent-pkg-linux-arm64, dsh-jsonrpc-agent-pkg-linux-x64, " + "dsh-jsonrpc-agent-pkg-macos-arm64" + ), + ): + build_python_release.stage_runtime( + tmp_path / "staging", + "1.2.3", + executable, + executable.name, + ) + + @pytest.mark.parametrize("target", ["linux-x64", "linux-arm64"]) def test_stage_runtime_copies_linux_executable_without_spawn_helper( tmp_path: Path, target: str diff --git a/scripts/build-python-release.py b/scripts/build-python-release.py index 6bbe8bf512..dc53853b39 100644 --- a/scripts/build-python-release.py +++ b/scripts/build-python-release.py @@ -26,6 +26,16 @@ SPAWN_HELPER_SUFFIX = "-spawn-helper" EXECUTABLE_TARGETS = {value[1]: key for key, value in PLATFORMS.items()} +def executable_target(executable_name: str) -> str: + try: + return EXECUTABLE_TARGETS[executable_name] + except KeyError as error: + supported = ", ".join(sorted(EXECUTABLE_TARGETS)) + raise ValueError( + f"unsupported runtime executable {executable_name!r}; expected one of: {supported}" + ) from error + + def spawn_helper_binary_target(header: bytes) -> str | None: if len(header) >= 8 and header[:4] == b"\xcf\xfa\xed\xfe": cpu_type = int.from_bytes(header[4:8], "little") @@ -158,7 +168,7 @@ def stage_runtime(destination: Path, version: str, executable: Path, executable_ raise FileNotFoundError(f"runtime executable does not exist: {executable}") if executable.stat().st_mode & stat.S_IXUSR == 0: raise PermissionError(f"runtime executable is not executable: {executable}") - expected_target = EXECUTABLE_TARGETS[executable_name] + expected_target = executable_target(executable_name) spawn_helper = Path(f"{executable}{SPAWN_HELPER_SUFFIX}") if expected_target.startswith("macos-"): if not spawn_helper.is_file(): @@ -204,7 +214,7 @@ def verify_wheel( assert platform is not None if len(executables) != 1 or not executables[0].endswith(f"/runtime/{platform[1]}"): raise RuntimeError(f"{wheel} must contain exactly {platform[1]}, found {executables}") - expected_target = EXECUTABLE_TARGETS[platform[1]] + expected_target = executable_target(platform[1]) expected_helper = f"{platform[1]}{SPAWN_HELPER_SUFFIX}" expected_helpers = [expected_helper] if expected_target.startswith("macos-") else [] found_helpers = [Path(helper).name for helper in helpers]