diff --git a/.github/workflows/build-native-action.yml b/.github/workflows/build-native-action.yml index 16eb6579..a4ec2bcb 100644 --- a/.github/workflows/build-native-action.yml +++ b/.github/workflows/build-native-action.yml @@ -307,6 +307,7 @@ jobs: - uses: actions/checkout@v3 - name: Set up Python 3.11 + id: setup-python uses: actions/setup-python@v5 with: python-version: '3.11' @@ -339,6 +340,16 @@ jobs: # SSE intrinsics in that break C compiles under the # v140 toolset Python 3.10/3.11 PCbuild targets. WindowsTargetPlatformVersion: "10.0.19041.0" + # CPython 3.10's PCbuild\find_python.bat only probes `py -3.9` + # / `py -3.8` before falling back to a nuget-based install of + # pythonx86. That nuget path is currently broken on + # windows-2022 ("The system cannot execute the specified + # program" from `nuget install pythonx86`). Point HOST_PYTHON + # at the setup-python interpreter so find_python.bat accepts + # it directly (checked before the py-launcher / nuget path) + # and never invokes nuget. 3.11+ probe newer py versions and + # are unaffected, but setting HOST_PYTHON for them is a no-op. + HOST_PYTHON: ${{ steps.setup-python.outputs.python-path }} run: | python -m relenv build --no-pretty --arch=${{ matrix.arch }} --python=${{ steps.python-version.outputs.version }} diff --git a/tests/test_runtime.py b/tests/test_runtime.py index 1fb3b86f..1f1ae572 100644 --- a/tests/test_runtime.py +++ b/tests/test_runtime.py @@ -175,6 +175,54 @@ def __init__(self, data: pathlib.Path) -> None: assert "x86_64-unknown-linux-gnu" in config_path.read_text() +def test_install_cargo_config_toolchain_permission_error( + tmp_path: pathlib.Path, monkeypatch: pytest.MonkeyPatch +) -> None: + """ + Regression for + https://github.com/saltstack/relenv/issues/252#issuecomment-4478458740. + + ``common().get_toolchain()`` calls ``os.makedirs(DATA_DIR)`` and can raise + ``PermissionError`` under a non-root process whose install dir isn't + writable. ``install_cargo_config`` catches the ``PermissionError`` but + then checks ``if not toolchain:``. If the local ``toolchain`` isn't + initialized before the ``try:``, the check fires ``UnboundLocalError: + local variable 'toolchain' referenced before assignment`` — surfacing as + a noisy traceback from ``site.addpackage`` on every interpreter start. + + ``install_cargo_config`` must degrade quietly (log via ``debug`` and + return) whether ``get_toolchain`` raises ``PermissionError`` or returns + ``None``. + """ + monkeypatch.setattr(relenv.runtime.sys, "platform", "linux") + data_dir = tmp_path / "data" + data_dir.mkdir() + + class StubDirs: + def __init__(self, data: pathlib.Path) -> None: + self.data = data + + stub_dirs = StubDirs(data_dir) + + def _raise_permission_error() -> pathlib.Path: + raise PermissionError("[Errno 13] Permission denied: '/opt/example/.local'") + + stub_common = SimpleNamespace( + DATA_DIR=tmp_path, + work_dirs=lambda: stub_dirs, + get_triplet=lambda: "x86_64-linux-gnu", + get_toolchain=_raise_permission_error, + ) + monkeypatch.setattr(relenv.runtime, "common", lambda: stub_common) + + # Must not raise UnboundLocalError (or anything else). + relenv.runtime.install_cargo_config() + + # And must not have written a cargo config, since there's no toolchain + # to point it at. + assert not (data_dir / "cargo" / "config.toml").exists() + + def test_build_shebang_value_error(monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setattr(relenv.runtime.sys, "RELENV", pathlib.Path("/rel"), raising=False) monkeypatch.setattr( diff --git a/tests/test_verify_build.py b/tests/test_verify_build.py index 76d73766..1c677b69 100644 --- a/tests/test_verify_build.py +++ b/tests/test_verify_build.py @@ -468,6 +468,17 @@ def test_pip_install_pyzmq( if pyzmq_version == "26.2.0" and sys.platform == "win32": pytest.xfail("vcredist not found as of 9/9/24") + if pyzmq_version == "26.2.0" and sys.platform == "linux": + # pyzmq 26.2.0's pyproject.toml uses scikit-build-core's + # `cmake.targets = ["pyzmq"]` option, which was renamed to + # `build.targets` in scikit-build-core 1.0.0 (released 2026-07-06). + # pyzmq 26.2.0 leaves scikit-build-core unpinned in build-system.requires, + # so pip picks up the newest release and the build errors out with: + # ERROR: Use build.targets instead of cmake.targets for + # scikit-build-core >= 0.10 + # Fixed upstream in pyzmq 26.4.0 (which uses build.targets). + pytest.xfail("pyzmq 26.2.0 incompatible with scikit-build-core >= 1.0") + if pyzmq_version == "26.4.0" and sys.platform == "win32": pytest.xfail("Needs troubleshooting 4/12/25")