From 93717cff17722093d0c069960c1de837951c1f24 Mon Sep 17 00:00:00 2001 From: LeSingh1 Date: Tue, 4 Aug 2026 15:30:22 -0700 Subject: [PATCH] Use pathlib in cuda.bindings build hooks and tests Part of NVIDIA#2410. Replaces os.path/os.sep with pathlib.Path in cuda_bindings/build_hooks.py and in the test modules that build paths to the test data, the examples directory and the reproducer cwd. Values handed to setuptools' Extension and to the cuFile string parameters stay str; only the path construction moves to pathlib. --- cuda_bindings/build_hooks.py | 25 +++++++++++++------------ cuda_bindings/tests/test_cuda.py | 4 ++-- cuda_bindings/tests/test_cufile.py | 13 ++++++------- cuda_bindings/tests/test_examples.py | 5 +++-- 4 files changed, 24 insertions(+), 23 deletions(-) diff --git a/cuda_bindings/build_hooks.py b/cuda_bindings/build_hooks.py index a50133f9777..0a1e7ef0563 100644 --- a/cuda_bindings/build_hooks.py +++ b/cuda_bindings/build_hooks.py @@ -16,6 +16,7 @@ import sys import sysconfig import tempfile +from pathlib import Path from warnings import warn from setuptools import build_meta as _build_meta @@ -50,9 +51,9 @@ def _import_get_cuda_path_or_home(): cuda = None for p in sys.path: - sp_cuda = os.path.join(p, "cuda") - if os.path.isdir(os.path.join(sp_cuda, "pathfinder")): - cuda.__path__ = list(cuda.__path__) + [sp_cuda] + sp_cuda = Path(p, "cuda") + if (sp_cuda / "pathfinder").is_dir(): + cuda.__path__ = list(cuda.__path__) + [str(sp_cuda)] break else: raise ModuleNotFoundError( @@ -79,11 +80,11 @@ def _get_cuda_path() -> str: def _rename_architecture_specific_files(): - path = os.path.join("cuda", "bindings", "_internal") + path = Path("cuda", "bindings", "_internal") if sys.platform == "linux": - src_files = glob.glob(os.path.join(path, "*_linux.pyx")) + src_files = glob.glob(str(path / "*_linux.pyx")) elif sys.platform == "win32": - src_files = glob.glob(os.path.join(path, "*_windows.pyx")) + src_files = glob.glob(str(path / "*_windows.pyx")) else: raise RuntimeError(f"platform is unrecognized: {sys.platform}") dst_files = [] @@ -103,7 +104,7 @@ def _prep_extensions(sources, libraries, include_dirs, library_dirs, extra_compi libraries = libraries if libraries else [] exts = [] for pyx in files: - mod_name = pyx.replace(".pyx", "").replace(os.sep, ".").replace("/", ".") + mod_name = ".".join(Path(pyx).with_suffix("").parts) exts.append( Extension( mod_name, @@ -149,16 +150,16 @@ def _build_cuda_bindings(debug=False): compile_for_coverage = bool(int(os.environ.get("CUDA_PYTHON_COVERAGE", "0"))) # Prepare compile/link arguments - include_path_list = [os.path.join(cuda_path, "include")] + include_path_list = [str(Path(cuda_path, "include"))] include_dirs = [ - os.path.dirname(sysconfig.get_path("include")), + str(Path(sysconfig.get_path("include")).parent), ] + include_path_list - library_dirs = [sysconfig.get_path("platlib"), os.path.join(os.sys.prefix, "lib")] + library_dirs = [sysconfig.get_path("platlib"), str(Path(os.sys.prefix, "lib"))] if sys.platform == "win32": cudalib_subdirs = [r"lib\arm64"] if sysconfig.get_platform() == "win-arm64" else [r"lib\x64"] else: cudalib_subdirs = ["lib64", "lib"] - library_dirs.extend(os.path.join(cuda_path, subdir) for subdir in cudalib_subdirs) + library_dirs.extend(str(Path(cuda_path, subdir)) for subdir in cudalib_subdirs) extra_compile_args = [] extra_link_args = [] @@ -201,7 +202,7 @@ def _cleanup_dst_files(): cuda_bindings_files = [f for f in cuda_bindings_files if "cufile" not in f] def get_static_libraries(f): - if os.path.basename(f) in ("runtime.pyx", "runtime_ptds.pyx"): + if Path(f).name in ("runtime.pyx", "runtime_ptds.pyx"): if sys.platform == "linux": return ["cudart_static", "rt"] else: diff --git a/cuda_bindings/tests/test_cuda.py b/cuda_bindings/tests/test_cuda.py index e2751df9237..5fea9bf207d 100644 --- a/cuda_bindings/tests/test_cuda.py +++ b/cuda_bindings/tests/test_cuda.py @@ -2,11 +2,11 @@ # SPDX-License-Identifier: Apache-2.0 import ctypes -import os.path import shutil import subprocess import sys import textwrap +from pathlib import Path import numpy as np import pytest @@ -1294,7 +1294,7 @@ def test_array_setter_no_double_free_after_clearing_with_empty_list(): params.attrs = [cuda.CUlaunchAttribute() for _ in range(8)] """ ) - proc = subprocess.run([sys.executable, "-c", code], capture_output=True, cwd=os.path.dirname(__file__)) # noqa: S603 + proc = subprocess.run([sys.executable, "-c", code], capture_output=True, cwd=Path(__file__).parent) # noqa: S603 assert proc.returncode == 0, ( f"reproducer subprocess exited with code {proc.returncode}; stderr: {proc.stderr.decode(errors='replace')}" ) diff --git a/cuda_bindings/tests/test_cufile.py b/cuda_bindings/tests/test_cufile.py index 46bd8429a62..55ac3de1ffb 100644 --- a/cuda_bindings/tests/test_cufile.py +++ b/cuda_bindings/tests/test_cufile.py @@ -41,10 +41,9 @@ def _cufile_driver_session(): def cufile_env_json(monkeypatch): """Set CUFILE_ENV_PATH_JSON environment variable for async tests.""" # Get absolute path to cufile.json in the same directory as this test file - test_dir = os.path.dirname(os.path.abspath(__file__)) - config_path = os.path.join(test_dir, "cufile.json") - assert os.path.isfile(config_path) - monkeypatch.setenv("CUFILE_ENV_PATH_JSON", config_path) + config_path = pathlib.Path(__file__).resolve().parent / "cufile.json" + assert config_path.is_file() + monkeypatch.setenv("CUFILE_ENV_PATH_JSON", str(config_path)) logging.info(f"Using cuFile config: {config_path}") @@ -1452,7 +1451,7 @@ def test_param(param, val): @pytest.mark.usefixtures("ctx", "cufile_env_json") def test_set_get_parameter_string(tmp_path): """Test setting and getting string parameters with cuFile validation.""" - temp_dir = tempfile.gettempdir() + temp_dir = pathlib.Path(tempfile.gettempdir()) # must be set to avoid getter error when testing ENV_LOGFILE_PATH... os.environ["CUFILE_LOGFILE_PATH"] = "" @@ -1460,12 +1459,12 @@ def test_set_get_parameter_string(tmp_path): (cufile.StringConfigParameter.LOGGING_LEVEL, "INFO", "DEBUG"), # Test logging level ( cufile.StringConfigParameter.ENV_LOGFILE_PATH, - os.path.join(temp_dir, "cufile.log"), + str(temp_dir / "cufile.log"), str(tmp_path / "cufile.log"), ), # Test environment log file path ( cufile.StringConfigParameter.LOG_DIR, - os.path.join(temp_dir, "cufile_logs"), + str(temp_dir / "cufile_logs"), str(tmp_path), ), # Test log directory ) diff --git a/cuda_bindings/tests/test_examples.py b/cuda_bindings/tests/test_examples.py index 652515830f8..a1757015ed5 100644 --- a/cuda_bindings/tests/test_examples.py +++ b/cuda_bindings/tests/test_examples.py @@ -5,12 +5,13 @@ import os import subprocess import sys +from pathlib import Path import pytest from cuda_python_test_helpers.pep723 import has_package_requirements_or_skip -examples_path = os.path.join(os.path.dirname(__file__), "..", "examples") -examples_files = glob.glob(os.path.join(examples_path, "**/*.py"), recursive=True) +examples_path = Path(__file__).parents[1] / "examples" +examples_files = glob.glob(str(examples_path / "**" / "*.py"), recursive=True) @pytest.mark.parametrize("example", examples_files)