From 9ef67b61037c117534d10ffa7d03445ed8d9c982 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Thu, 6 Aug 2026 01:58:51 -0700 Subject: [PATCH] build: report cuda-bindings provenance in PEP 517 builds Resolve the CUDA path before importing cuda.bindings so the existing pathfinder import repairs PEP 517 namespace shadowing first. Reuse the resolved path for the CUDA include directory. --- cuda_core/build_hooks.py | 5 ++++- cuda_core/tests/test_build_hooks.py | 30 +++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/cuda_core/build_hooks.py b/cuda_core/build_hooks.py index 05cc9267726..626d50355ab 100644 --- a/cuda_core/build_hooks.py +++ b/cuda_core/build_hooks.py @@ -133,6 +133,9 @@ def _build_cuda_core(debug=False): # This function populates "_extensions". global _extensions + # Resolve CUDA first so the pathfinder import repairs PEP 517 namespace shadowing before importing bindings. + cuda_path = _get_cuda_path() + # Add cuda-bindings to sys.path so Cython can find .pxd files # This is needed for editable installs where meta path finders don't work for Cython # We need to add the directory containing the 'cuda' package so Cython can resolve @@ -178,7 +181,7 @@ def get_sources(mod_name): return sources - all_include_dirs = [os.path.join(_get_cuda_path(), "include")] + all_include_dirs = [os.path.join(cuda_path, "include")] extra_compile_args = [] extra_link_args = [] extra_cythonize_kwargs = {} diff --git a/cuda_core/tests/test_build_hooks.py b/cuda_core/tests/test_build_hooks.py index 121ed1be053..c08ad4cd3c5 100644 --- a/cuda_core/tests/test_build_hooks.py +++ b/cuda_core/tests/test_build_hooks.py @@ -16,6 +16,7 @@ These tests require Cython to be installed (build_hooks.py imports it). """ +import builtins import importlib.util import os import tempfile @@ -50,6 +51,35 @@ def _load_build_hooks(): build_hooks = _load_build_hooks() +@pytest.mark.agent_authored(model="gpt-5.6") +def test_cuda_path_is_resolved_before_importing_bindings(monkeypatch): + """PEP 517 namespace repair runs before cuda.bindings is imported.""" + events = [] + + class StopBuildError(Exception): + pass + + def get_cuda_path(): + events.append("cuda-path") + return "/cuda" + + original_import = builtins.__import__ + + def stop_at_bindings_import(name, *args, **kwargs): + if name == "cuda.bindings": + events.append("cuda-bindings") + raise StopBuildError + return original_import(name, *args, **kwargs) + + monkeypatch.setattr(build_hooks, "_get_cuda_path", get_cuda_path) + monkeypatch.setattr(builtins, "__import__", stop_at_bindings_import) + + with pytest.raises(StopBuildError): + build_hooks._build_cuda_core() + + assert events == ["cuda-path", "cuda-bindings"] + + def _check_version_detection( cuda_version, expected_major, *, use_cuda_path=True, use_cuda_home=False, cuda_core_build_major=None ):