Skip to content

Commit 9f7793c

Browse files
committed
build: use cuda.pathfinder in build hooks with namespace fix
Replace the temporary namespace diagnostic with _import_get_cuda_path_or_home which works around PEP 517 namespace shadowing: in isolated build envs, backend-path=["."] causes the cuda namespace to resolve to only the project's cuda/ dir, hiding the installed cuda-pathfinder. The fix replaces the _NamespacePath with a plain list that includes the site-packages cuda/ dir. Made-with: Cursor
1 parent 8a49f6a commit 9f7793c

2 files changed

Lines changed: 62 additions & 78 deletions

File tree

cuda_bindings/build_hooks.py

Lines changed: 31 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -33,53 +33,45 @@
3333
_extensions = None
3434

3535

36+
def _import_get_cuda_path_or_home():
37+
"""Import get_cuda_path_or_home, working around PEP 517 namespace shadowing.
38+
39+
In isolated build environments, backend-path=["."] causes the ``cuda``
40+
namespace package to resolve to only the project's ``cuda/`` directory,
41+
hiding ``cuda.pathfinder`` installed in the build-env's site-packages.
42+
Fix by replacing ``cuda.__path__`` with a plain list that includes the
43+
site-packages ``cuda/`` directory.
44+
"""
45+
try:
46+
from cuda import pathfinder
47+
except ModuleNotFoundError:
48+
pass
49+
else:
50+
return pathfinder.get_cuda_path_or_home
51+
52+
import cuda
53+
54+
for p in sys.path:
55+
sp_cuda = os.path.join(p, "cuda")
56+
if os.path.isdir(os.path.join(sp_cuda, "pathfinder")):
57+
cuda.__path__ = list(cuda.__path__) + [sp_cuda]
58+
break
59+
60+
from cuda.pathfinder import get_cuda_path_or_home
61+
62+
return get_cuda_path_or_home
63+
64+
3665
@functools.cache
3766
def _get_cuda_path() -> str:
38-
_diagnose_namespace_packages()
39-
cuda_path = os.environ.get("CUDA_PATH", os.environ.get("CUDA_HOME"))
67+
get_cuda_path_or_home = _import_get_cuda_path_or_home()
68+
cuda_path = get_cuda_path_or_home()
4069
if not cuda_path:
4170
raise RuntimeError("Environment variable CUDA_PATH or CUDA_HOME is not set")
4271
print("CUDA path:", cuda_path)
4372
return cuda_path
4473

4574

46-
def _diagnose_namespace_packages():
47-
"""TODO: temporary diagnostic — remove after investigating namespace package resolution."""
48-
import sys
49-
50-
print("--- namespace diagnostic (cuda_bindings/build_hooks.py) ---")
51-
print("sys.path:")
52-
for p in sys.path:
53-
print(f" {p}")
54-
try:
55-
import cuda
56-
57-
print(f"cuda.__path__: {cuda.__path__}")
58-
print(f"cuda.__file__: {getattr(cuda, '__file__', 'N/A')}")
59-
print(f"cuda.__spec__: {cuda.__spec__}")
60-
except Exception as e:
61-
print(f"import cuda failed: {e}")
62-
try:
63-
import cuda.pathfinder
64-
65-
print(f"cuda.pathfinder.__file__: {cuda.pathfinder.__file__}")
66-
print(f"cuda.pathfinder.__version__: {cuda.pathfinder.__version__}")
67-
except Exception as e:
68-
print(f"import cuda.pathfinder failed (before extend_path): {e}")
69-
try:
70-
import pkgutil
71-
72-
cuda.__path__ = pkgutil.extend_path(cuda.__path__, cuda.__name__)
73-
print(f"cuda.__path__ (after extend_path): {cuda.__path__}")
74-
import cuda.pathfinder
75-
76-
print(f"cuda.pathfinder.__file__: {cuda.pathfinder.__file__}")
77-
print(f"cuda.pathfinder.__version__: {cuda.pathfinder.__version__}")
78-
except Exception as e2:
79-
print(f"import cuda.pathfinder failed (after extend_path): {e2}")
80-
print("--- end namespace diagnostic ---")
81-
82-
8375
# -----------------------------------------------------------------------
8476
# Header parsing helpers (called only from _build_cuda_bindings)
8577

cuda_core/build_hooks.py

Lines changed: 31 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -28,53 +28,45 @@
2828
COMPILE_FOR_COVERAGE = bool(int(os.environ.get("CUDA_PYTHON_COVERAGE", "0")))
2929

3030

31+
def _import_get_cuda_path_or_home():
32+
"""Import get_cuda_path_or_home, working around PEP 517 namespace shadowing.
33+
34+
In isolated build environments, backend-path=["."] causes the ``cuda``
35+
namespace package to resolve to only the project's ``cuda/`` directory,
36+
hiding ``cuda.pathfinder`` installed in the build-env's site-packages.
37+
Fix by replacing ``cuda.__path__`` with a plain list that includes the
38+
site-packages ``cuda/`` directory.
39+
"""
40+
try:
41+
from cuda import pathfinder
42+
except ModuleNotFoundError:
43+
pass
44+
else:
45+
return pathfinder.get_cuda_path_or_home
46+
47+
import cuda
48+
49+
for p in sys.path:
50+
sp_cuda = os.path.join(p, "cuda")
51+
if os.path.isdir(os.path.join(sp_cuda, "pathfinder")):
52+
cuda.__path__ = list(cuda.__path__) + [sp_cuda]
53+
break
54+
55+
from cuda.pathfinder import get_cuda_path_or_home
56+
57+
return get_cuda_path_or_home
58+
59+
3160
@functools.cache
3261
def _get_cuda_path() -> str:
33-
_diagnose_namespace_packages()
34-
cuda_path = os.environ.get("CUDA_PATH", os.environ.get("CUDA_HOME"))
62+
get_cuda_path_or_home = _import_get_cuda_path_or_home()
63+
cuda_path = get_cuda_path_or_home()
3564
if not cuda_path:
3665
raise RuntimeError("Environment variable CUDA_PATH or CUDA_HOME is not set")
3766
print("CUDA path:", cuda_path)
3867
return cuda_path
3968

4069

41-
def _diagnose_namespace_packages():
42-
"""TODO: temporary diagnostic — remove after investigating namespace package resolution."""
43-
import sys
44-
45-
print("--- namespace diagnostic (cuda_core/build_hooks.py) ---")
46-
print("sys.path:")
47-
for p in sys.path:
48-
print(f" {p}")
49-
try:
50-
import cuda
51-
52-
print(f"cuda.__path__: {cuda.__path__}")
53-
print(f"cuda.__file__: {getattr(cuda, '__file__', 'N/A')}")
54-
print(f"cuda.__spec__: {cuda.__spec__}")
55-
except Exception as e:
56-
print(f"import cuda failed: {e}")
57-
try:
58-
import cuda.pathfinder
59-
60-
print(f"cuda.pathfinder.__file__: {cuda.pathfinder.__file__}")
61-
print(f"cuda.pathfinder.__version__: {cuda.pathfinder.__version__}")
62-
except Exception as e:
63-
print(f"import cuda.pathfinder failed (before extend_path): {e}")
64-
try:
65-
import pkgutil
66-
67-
cuda.__path__ = pkgutil.extend_path(cuda.__path__, cuda.__name__)
68-
print(f"cuda.__path__ (after extend_path): {cuda.__path__}")
69-
import cuda.pathfinder
70-
71-
print(f"cuda.pathfinder.__file__: {cuda.pathfinder.__file__}")
72-
print(f"cuda.pathfinder.__version__: {cuda.pathfinder.__version__}")
73-
except Exception as e2:
74-
print(f"import cuda.pathfinder failed (after extend_path): {e2}")
75-
print("--- end namespace diagnostic ---")
76-
77-
7870
@functools.cache
7971
def _determine_cuda_major_version() -> str:
8072
"""Determine the CUDA major version for building cuda.core.

0 commit comments

Comments
 (0)