Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .github/workflows/build-native-action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -339,6 +340,16 @@ jobs:
# SSE intrinsics in <wchar.h> 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 }}

Expand Down
48 changes: 48 additions & 0 deletions tests/test_runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
11 changes: 11 additions & 0 deletions tests/test_verify_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")

Expand Down
Loading