From 2e9fb5be85e5fd51269fef0090dc3ab35640b4cf Mon Sep 17 00:00:00 2001 From: brandon-b-miller Date: Tue, 27 Jan 2026 08:02:33 -0800 Subject: [PATCH 1/7] initial --- .../tests/test_find_nvidia_headers.py | 101 ++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/cuda_pathfinder/tests/test_find_nvidia_headers.py b/cuda_pathfinder/tests/test_find_nvidia_headers.py index 494d7c0ae9..a42823ae31 100644 --- a/cuda_pathfinder/tests/test_find_nvidia_headers.py +++ b/cuda_pathfinder/tests/test_find_nvidia_headers.py @@ -20,6 +20,7 @@ import pytest from cuda.pathfinder import find_nvidia_header_directory +from cuda.pathfinder._headers.find_nvidia_headers import FoundHeader from cuda.pathfinder._headers.supported_nvidia_headers import ( SUPPORTED_HEADERS_CTK, SUPPORTED_HEADERS_CTK_ALL, @@ -97,3 +98,103 @@ def test_find_ctk_headers(info_summary_append, libname): assert os.path.isfile(os.path.join(hdr_dir, h_filename)) if STRICTNESS == "all_must_work": assert hdr_dir is not None + + +def test_unknown_libname_with_info(): + """Test that find_nvidia_header_directory_with_info raises for unknown libraries.""" + with pytest.raises(RuntimeError, match=r"^UNKNOWN libname='unknown-libname'$"): + find_nvidia_header_directory("unknown-libname", include_info=True) + + +@pytest.mark.parametrize("libname", SUPPORTED_HEADERS_NON_CTK.keys()) +def test_find_non_ctk_headers_with_info(info_summary_append, libname): + """Test find_nvidia_header_directory_with_info for non-CTK libraries. + + This test validates: + 1. The function returns FoundHeader or None (not just a string) + 2. The abs_path matches what the original function returns + 3. The found_via field correctly identifies the discovery method + """ + found_header = find_nvidia_header_directory(libname, include_info=True) + hdr_dir_original = find_nvidia_header_directory(libname) + + info_summary_append(f"{found_header=!r}") + + # Test consistency between old and new API + if found_header: + assert isinstance(found_header, FoundHeader) + assert found_header.abs_path == hdr_dir_original + assert os.path.isdir(found_header.abs_path) + assert os.path.isfile(os.path.join(found_header.abs_path, SUPPORTED_HEADERS_NON_CTK[libname])) + + # Validate found_via field + assert found_header.found_via in ("site-packages", "conda", "CUDA_HOME") + info_summary_append(f"found_via={found_header.found_via!r}") + else: + assert hdr_dir_original is None + + # Test expected discovery methods based on environment + if have_distribution_for(libname): + assert found_header is not None + # When installed via pip wheel, should be found in site-packages + assert found_header.found_via == "site-packages" + hdr_dir_parts = found_header.abs_path.split(os.path.sep) + assert "site-packages" in hdr_dir_parts + elif STRICTNESS == "all_must_work": + assert found_header is not None + if conda_prefix := os.environ.get("CONDA_PREFIX"): + # When in conda environment, should be found via conda + assert found_header.found_via == "conda" + assert found_header.abs_path.startswith(conda_prefix) + else: + # Otherwise should be found via system install (CUDA_HOME) + assert found_header.found_via == "CUDA_HOME" + inst_dirs = SUPPORTED_INSTALL_DIRS_NON_CTK.get(libname) + if inst_dirs is not None: + for inst_dir in inst_dirs: + globbed = glob.glob(inst_dir) + if found_header.abs_path in globbed: + break + else: + raise RuntimeError(f"{found_header.abs_path=} does not match any {inst_dirs=}") + + +@pytest.mark.parametrize("libname", SUPPORTED_HEADERS_CTK.keys()) +def test_find_ctk_headers_with_info(info_summary_append, libname): + """Test find_nvidia_header_directory_with_info for CTK libraries. + + This test validates: + 1. The function returns FoundHeader or None (not just a string) + 2. The abs_path matches what the original function returns + 3. The found_via field correctly identifies the discovery method (site-packages, conda, or CUDA_HOME) + """ + found_header = find_nvidia_header_directory(libname, include_info=True) + hdr_dir_original = find_nvidia_header_directory(libname, include_info=False) + + info_summary_append(f"{found_header=!r}") + + # Test consistency between old and new API + if found_header: + assert isinstance(found_header, FoundHeader) + assert found_header.abs_path == hdr_dir_original + assert os.path.isdir(found_header.abs_path) + h_filename = SUPPORTED_HEADERS_CTK[libname] + assert os.path.isfile(os.path.join(found_header.abs_path, h_filename)) + + # Validate found_via field + assert found_header.found_via in ("site-packages", "conda", "CUDA_HOME") + info_summary_append(f"found_via={found_header.found_via!r}") + else: + assert hdr_dir_original is None + + if STRICTNESS == "all_must_work": + assert found_header is not None + # In CI, CTK headers can come from: + # - site-packages wheels (when LOCAL_CTK=0 and extra wheels installed) + # - CUDA_HOME (when LOCAL_CTK=1 and mini CTK is set up) + # - conda (when CONDA_PREFIX is set) + + if os.environ.get("CONDA_PREFIX"): + assert found_header.found_via == "conda" + elif os.environ.get("CUDA_HOME") or os.environ.get("CUDA_PATH"): + assert found_header.found_via == "CUDA_HOME" From 806c907c3b004de1b54300f5244bcfc2034976d5 Mon Sep 17 00:00:00 2001 From: brandon-b-miller Date: Tue, 27 Jan 2026 08:04:19 -0800 Subject: [PATCH 2/7] resolve a few tests --- cuda_pathfinder/cuda/pathfinder/__init__.py | 1 + .../_headers/find_nvidia_headers.py | 52 ++++++++++++++----- 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/cuda_pathfinder/cuda/pathfinder/__init__.py b/cuda_pathfinder/cuda/pathfinder/__init__.py index 8da4020116..26d5ebc999 100644 --- a/cuda_pathfinder/cuda/pathfinder/__init__.py +++ b/cuda_pathfinder/cuda/pathfinder/__init__.py @@ -9,6 +9,7 @@ from cuda.pathfinder._dynamic_libs.supported_nvidia_libs import ( SUPPORTED_LIBNAMES as SUPPORTED_NVIDIA_LIBNAMES, # noqa: F401 ) +from cuda.pathfinder._headers.find_nvidia_headers import FoundHeader as FoundHeader from cuda.pathfinder._headers.find_nvidia_headers import find_nvidia_header_directory as find_nvidia_header_directory from cuda.pathfinder._headers.supported_nvidia_headers import SUPPORTED_HEADERS_CTK as _SUPPORTED_HEADERS_CTK diff --git a/cuda_pathfinder/cuda/pathfinder/_headers/find_nvidia_headers.py b/cuda_pathfinder/cuda/pathfinder/_headers/find_nvidia_headers.py index 63f8a627fd..43a66087d5 100644 --- a/cuda_pathfinder/cuda/pathfinder/_headers/find_nvidia_headers.py +++ b/cuda_pathfinder/cuda/pathfinder/_headers/find_nvidia_headers.py @@ -4,6 +4,7 @@ import functools import glob import os +from dataclasses import dataclass from cuda.pathfinder._headers import supported_nvidia_headers from cuda.pathfinder._utils.env_vars import get_cuda_home_or_path @@ -11,6 +12,16 @@ from cuda.pathfinder._utils.platform_aware import IS_WINDOWS +@dataclass +class FoundHeader: + abs_path: str + found_via: str + + def _normalize_path(self) -> str | None: + self.abs_path = _abs_norm(self.abs_path) + return self + + def _abs_norm(path: str | None) -> str | None: if path: return os.path.normpath(os.path.abspath(path)) @@ -21,12 +32,12 @@ def _joined_isfile(dirpath: str, basename: str) -> bool: return os.path.isfile(os.path.join(dirpath, basename)) -def _find_under_site_packages(sub_dir: str, h_basename: str) -> str | None: +def _find_under_site_packages(sub_dir: str, h_basename: str) -> FoundHeader | None: # Installed from a wheel hdr_dir: str # help mypy for hdr_dir in find_sub_dirs_all_sitepackages(tuple(sub_dir.split("/"))): if _joined_isfile(hdr_dir, h_basename): - return hdr_dir + return FoundHeader(abs_path=hdr_dir, found_via="site-packages") return None @@ -52,7 +63,7 @@ def _find_based_on_ctk_layout(libname: str, h_basename: str, anchor_point: str) return None -def _find_based_on_conda_layout(libname: str, h_basename: str, ctk_layout: bool) -> str | None: +def _find_based_on_conda_layout(libname: str, h_basename: str, ctk_layout: bool) -> FoundHeader | None: conda_prefix = os.environ.get("CONDA_PREFIX") if not conda_prefix: return None @@ -73,10 +84,13 @@ def _find_based_on_conda_layout(libname: str, h_basename: str, ctk_layout: bool) else: include_path = os.path.join(conda_prefix, "include") anchor_point = os.path.dirname(include_path) - return _find_based_on_ctk_layout(libname, h_basename, anchor_point) + found_header_path = _find_based_on_ctk_layout(libname, h_basename, anchor_point) + if found_header_path: + return FoundHeader(abs_path=found_header_path, found_via="conda") + return None -def _find_ctk_header_directory(libname: str) -> str | None: +def _find_ctk_header_directory(libname: str) -> FoundHeader | None: h_basename = supported_nvidia_headers.SUPPORTED_HEADERS_CTK[libname] candidate_dirs = supported_nvidia_headers.SUPPORTED_SITE_PACKAGE_HEADER_DIRS_CTK[libname] @@ -90,18 +104,19 @@ def _find_ctk_header_directory(libname: str) -> str | None: cuda_home = get_cuda_home_or_path() if cuda_home: # noqa: SIM102 if result := _find_based_on_ctk_layout(libname, h_basename, cuda_home): - return result + return FoundHeader(abs_path=result, found_via="CUDA_HOME") return None @functools.cache -def find_nvidia_header_directory(libname: str) -> str | None: +def find_nvidia_header_directory(libname: str, include_info: bool = False) -> FoundHeader | str | None: """Locate the header directory for a supported NVIDIA library. Args: libname (str): The short name of the library whose headers are needed (e.g., ``"nvrtc"``, ``"cusolver"``, ``"nvshmem"``). + include_info (bool): Whether to include information about the discovery method in the FoundHeader. Returns: str or None: Absolute path to the discovered header directory, or ``None`` @@ -127,25 +142,34 @@ def find_nvidia_header_directory(libname: str) -> str | None: """ if libname in supported_nvidia_headers.SUPPORTED_HEADERS_CTK: - return _abs_norm(_find_ctk_header_directory(libname)) + found_hdr = _find_ctk_header_directory(libname) + if found_hdr: + found_hdr._normalize_path() + return found_hdr if include_info else found_hdr.abs_path + return None h_basename = supported_nvidia_headers.SUPPORTED_HEADERS_NON_CTK.get(libname) if h_basename is None: raise RuntimeError(f"UNKNOWN {libname=}") candidate_dirs = supported_nvidia_headers.SUPPORTED_SITE_PACKAGE_HEADER_DIRS_NON_CTK.get(libname, []) - hdr_dir: str | None # help mypy + found_hdr: FoundHeader | None # help mypy for cdir in candidate_dirs: - if hdr_dir := _find_under_site_packages(cdir, h_basename): - return _abs_norm(hdr_dir) + if found_hdr := _find_under_site_packages(cdir, h_basename): + found_hdr._normalize_path() + return found_hdr if include_info else found_hdr.abs_path - if hdr_dir := _find_based_on_conda_layout(libname, h_basename, False): - return _abs_norm(hdr_dir) + if found_hdr := _find_based_on_conda_layout(libname, h_basename, False): + found_hdr._normalize_path() + return found_hdr if include_info else found_hdr.abs_path + if include_info: + # TODO: what to do here? + raise RuntimeError candidate_dirs = supported_nvidia_headers.SUPPORTED_INSTALL_DIRS_NON_CTK.get(libname, []) for cdir in candidate_dirs: for hdr_dir in sorted(glob.glob(cdir), reverse=True): if _joined_isfile(hdr_dir, h_basename): return _abs_norm(hdr_dir) - return None + From 1f1651855e1db55ead663d822691650b0ceb8de0 Mon Sep 17 00:00:00 2001 From: brandon-b-miller Date: Tue, 27 Jan 2026 08:11:06 -0800 Subject: [PATCH 3/7] precommit --- .../cuda/pathfinder/_headers/find_nvidia_headers.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/cuda_pathfinder/cuda/pathfinder/_headers/find_nvidia_headers.py b/cuda_pathfinder/cuda/pathfinder/_headers/find_nvidia_headers.py index 43a66087d5..81c18fa025 100644 --- a/cuda_pathfinder/cuda/pathfinder/_headers/find_nvidia_headers.py +++ b/cuda_pathfinder/cuda/pathfinder/_headers/find_nvidia_headers.py @@ -1,6 +1,8 @@ # SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 +from __future__ import annotations + import functools import glob import os @@ -14,10 +16,10 @@ @dataclass class FoundHeader: - abs_path: str + abs_path: str | None found_via: str - def _normalize_path(self) -> str | None: + def _normalize_path(self) -> FoundHeader: self.abs_path = _abs_norm(self.abs_path) return self @@ -153,7 +155,7 @@ def find_nvidia_header_directory(libname: str, include_info: bool = False) -> Fo raise RuntimeError(f"UNKNOWN {libname=}") candidate_dirs = supported_nvidia_headers.SUPPORTED_SITE_PACKAGE_HEADER_DIRS_NON_CTK.get(libname, []) - found_hdr: FoundHeader | None # help mypy + for cdir in candidate_dirs: if found_hdr := _find_under_site_packages(cdir, h_basename): found_hdr._normalize_path() @@ -172,4 +174,3 @@ def find_nvidia_header_directory(libname: str, include_info: bool = False) -> Fo if _joined_isfile(hdr_dir, h_basename): return _abs_norm(hdr_dir) return None - From aa8e322b7f2c35a50cd7398f7a2050ad87e1bd2a Mon Sep 17 00:00:00 2001 From: brandon-b-miller Date: Wed, 28 Jan 2026 07:33:52 -0800 Subject: [PATCH 4/7] address reviews --- cuda_pathfinder/cuda/pathfinder/__init__.py | 5 +- .../_headers/find_nvidia_headers.py | 77 ++++++++++++------- .../tests/test_find_nvidia_headers.py | 31 +++----- 3 files changed, 67 insertions(+), 46 deletions(-) diff --git a/cuda_pathfinder/cuda/pathfinder/__init__.py b/cuda_pathfinder/cuda/pathfinder/__init__.py index 26d5ebc999..e905a839c5 100644 --- a/cuda_pathfinder/cuda/pathfinder/__init__.py +++ b/cuda_pathfinder/cuda/pathfinder/__init__.py @@ -9,8 +9,11 @@ from cuda.pathfinder._dynamic_libs.supported_nvidia_libs import ( SUPPORTED_LIBNAMES as SUPPORTED_NVIDIA_LIBNAMES, # noqa: F401 ) -from cuda.pathfinder._headers.find_nvidia_headers import FoundHeader as FoundHeader +from cuda.pathfinder._headers.find_nvidia_headers import FoundHeaderDir as FoundHeaderDir from cuda.pathfinder._headers.find_nvidia_headers import find_nvidia_header_directory as find_nvidia_header_directory +from cuda.pathfinder._headers.find_nvidia_headers import ( + locate_nvidia_header_directory as locate_nvidia_header_directory, +) from cuda.pathfinder._headers.supported_nvidia_headers import SUPPORTED_HEADERS_CTK as _SUPPORTED_HEADERS_CTK from cuda.pathfinder._version import __version__ # isort: skip # noqa: F401 diff --git a/cuda_pathfinder/cuda/pathfinder/_headers/find_nvidia_headers.py b/cuda_pathfinder/cuda/pathfinder/_headers/find_nvidia_headers.py index 81c18fa025..3039cf208d 100644 --- a/cuda_pathfinder/cuda/pathfinder/_headers/find_nvidia_headers.py +++ b/cuda_pathfinder/cuda/pathfinder/_headers/find_nvidia_headers.py @@ -15,13 +15,12 @@ @dataclass -class FoundHeader: +class FoundHeaderDir: abs_path: str | None found_via: str - def _normalize_path(self) -> FoundHeader: + def __post_init__(self) -> None: self.abs_path = _abs_norm(self.abs_path) - return self def _abs_norm(path: str | None) -> str | None: @@ -34,12 +33,12 @@ def _joined_isfile(dirpath: str, basename: str) -> bool: return os.path.isfile(os.path.join(dirpath, basename)) -def _find_under_site_packages(sub_dir: str, h_basename: str) -> FoundHeader | None: +def _find_under_site_packages(sub_dir: str, h_basename: str) -> FoundHeaderDir | None: # Installed from a wheel hdr_dir: str # help mypy for hdr_dir in find_sub_dirs_all_sitepackages(tuple(sub_dir.split("/"))): if _joined_isfile(hdr_dir, h_basename): - return FoundHeader(abs_path=hdr_dir, found_via="site-packages") + return FoundHeaderDir(abs_path=hdr_dir, found_via="site-packages") return None @@ -65,7 +64,7 @@ def _find_based_on_ctk_layout(libname: str, h_basename: str, anchor_point: str) return None -def _find_based_on_conda_layout(libname: str, h_basename: str, ctk_layout: bool) -> FoundHeader | None: +def _find_based_on_conda_layout(libname: str, h_basename: str, ctk_layout: bool) -> FoundHeaderDir | None: conda_prefix = os.environ.get("CONDA_PREFIX") if not conda_prefix: return None @@ -88,11 +87,11 @@ def _find_based_on_conda_layout(libname: str, h_basename: str, ctk_layout: bool) anchor_point = os.path.dirname(include_path) found_header_path = _find_based_on_ctk_layout(libname, h_basename, anchor_point) if found_header_path: - return FoundHeader(abs_path=found_header_path, found_via="conda") + return FoundHeaderDir(abs_path=found_header_path, found_via="conda") return None -def _find_ctk_header_directory(libname: str) -> FoundHeader | None: +def _find_ctk_header_directory(libname: str) -> FoundHeaderDir | None: h_basename = supported_nvidia_headers.SUPPORTED_HEADERS_CTK[libname] candidate_dirs = supported_nvidia_headers.SUPPORTED_SITE_PACKAGE_HEADER_DIRS_CTK[libname] @@ -106,23 +105,23 @@ def _find_ctk_header_directory(libname: str) -> FoundHeader | None: cuda_home = get_cuda_home_or_path() if cuda_home: # noqa: SIM102 if result := _find_based_on_ctk_layout(libname, h_basename, cuda_home): - return FoundHeader(abs_path=result, found_via="CUDA_HOME") + return FoundHeaderDir(abs_path=result, found_via="CUDA_HOME") return None @functools.cache -def find_nvidia_header_directory(libname: str, include_info: bool = False) -> FoundHeader | str | None: +def locate_nvidia_header_directory(libname: str) -> FoundHeaderDir | None: """Locate the header directory for a supported NVIDIA library. Args: libname (str): The short name of the library whose headers are needed (e.g., ``"nvrtc"``, ``"cusolver"``, ``"nvshmem"``). - include_info (bool): Whether to include information about the discovery method in the FoundHeader. Returns: - str or None: Absolute path to the discovered header directory, or ``None`` - if the headers cannot be found. + FoundHeaderDir or None: A FoundHeaderDir object containing the absolute path + to the discovered header directory and information about where it was found, + or ``None`` if the headers cannot be found. Raises: RuntimeError: If ``libname`` is not in the supported set. @@ -144,11 +143,7 @@ def find_nvidia_header_directory(libname: str, include_info: bool = False) -> Fo """ if libname in supported_nvidia_headers.SUPPORTED_HEADERS_CTK: - found_hdr = _find_ctk_header_directory(libname) - if found_hdr: - found_hdr._normalize_path() - return found_hdr if include_info else found_hdr.abs_path - return None + return _find_ctk_header_directory(libname) h_basename = supported_nvidia_headers.SUPPORTED_HEADERS_NON_CTK.get(libname) if h_basename is None: @@ -158,19 +153,49 @@ def find_nvidia_header_directory(libname: str, include_info: bool = False) -> Fo for cdir in candidate_dirs: if found_hdr := _find_under_site_packages(cdir, h_basename): - found_hdr._normalize_path() - return found_hdr if include_info else found_hdr.abs_path + return found_hdr if found_hdr := _find_based_on_conda_layout(libname, h_basename, False): - found_hdr._normalize_path() - return found_hdr if include_info else found_hdr.abs_path + return found_hdr - if include_info: - # TODO: what to do here? - raise RuntimeError + # Fall back to system install directories candidate_dirs = supported_nvidia_headers.SUPPORTED_INSTALL_DIRS_NON_CTK.get(libname, []) for cdir in candidate_dirs: for hdr_dir in sorted(glob.glob(cdir), reverse=True): if _joined_isfile(hdr_dir, h_basename): - return _abs_norm(hdr_dir) + # For system installs, we don't have a clear found_via, so use "system" + return FoundHeaderDir(abs_path=hdr_dir, found_via="supported_install_dir") return None + + +def find_nvidia_header_directory(libname: str) -> str | None: + """Locate the header directory for a supported NVIDIA library. + + Args: + libname (str): The short name of the library whose headers are needed + (e.g., ``"nvrtc"``, ``"cusolver"``, ``"nvshmem"``). + + Returns: + str or None: Absolute path to the discovered header directory, or ``None`` + if the headers cannot be found. + + Raises: + RuntimeError: If ``libname`` is not in the supported set. + + Search order: + 1. **NVIDIA Python wheels** + + - Scan installed distributions (``site-packages``) for header layouts + shipped in NVIDIA wheels (e.g., ``cuda-toolkit[nvrtc]``). + + 2. **Conda environments** + + - Check Conda-style installation prefixes, which use platform-specific + include directory layouts. + + 3. **CUDA Toolkit environment variables** + + - Use ``CUDA_HOME`` or ``CUDA_PATH`` (in that order). + """ + found = locate_nvidia_header_directory(libname) + return found.abs_path if found else None diff --git a/cuda_pathfinder/tests/test_find_nvidia_headers.py b/cuda_pathfinder/tests/test_find_nvidia_headers.py index a42823ae31..6a650d7963 100644 --- a/cuda_pathfinder/tests/test_find_nvidia_headers.py +++ b/cuda_pathfinder/tests/test_find_nvidia_headers.py @@ -19,8 +19,8 @@ import pytest -from cuda.pathfinder import find_nvidia_header_directory -from cuda.pathfinder._headers.find_nvidia_headers import FoundHeader +from cuda.pathfinder import find_nvidia_header_directory, locate_nvidia_header_directory +from cuda.pathfinder._headers.find_nvidia_headers import FoundHeaderDir from cuda.pathfinder._headers.supported_nvidia_headers import ( SUPPORTED_HEADERS_CTK, SUPPORTED_HEADERS_CTK_ALL, @@ -101,9 +101,9 @@ def test_find_ctk_headers(info_summary_append, libname): def test_unknown_libname_with_info(): - """Test that find_nvidia_header_directory_with_info raises for unknown libraries.""" + """Test that locate_nvidia_header_directory raises for unknown libraries.""" with pytest.raises(RuntimeError, match=r"^UNKNOWN libname='unknown-libname'$"): - find_nvidia_header_directory("unknown-libname", include_info=True) + locate_nvidia_header_directory("unknown-libname") @pytest.mark.parametrize("libname", SUPPORTED_HEADERS_NON_CTK.keys()) @@ -111,23 +111,21 @@ def test_find_non_ctk_headers_with_info(info_summary_append, libname): """Test find_nvidia_header_directory_with_info for non-CTK libraries. This test validates: - 1. The function returns FoundHeader or None (not just a string) + 1. The function returns FoundHeaderDir or None (not just a string) 2. The abs_path matches what the original function returns 3. The found_via field correctly identifies the discovery method """ - found_header = find_nvidia_header_directory(libname, include_info=True) + found_header = find_nvidia_header_directory(libname) hdr_dir_original = find_nvidia_header_directory(libname) info_summary_append(f"{found_header=!r}") - # Test consistency between old and new API if found_header: - assert isinstance(found_header, FoundHeader) + assert isinstance(found_header, FoundHeaderDir) assert found_header.abs_path == hdr_dir_original assert os.path.isdir(found_header.abs_path) assert os.path.isfile(os.path.join(found_header.abs_path, SUPPORTED_HEADERS_NON_CTK[libname])) - # Validate found_via field assert found_header.found_via in ("site-packages", "conda", "CUDA_HOME") info_summary_append(f"found_via={found_header.found_via!r}") else: @@ -136,18 +134,15 @@ def test_find_non_ctk_headers_with_info(info_summary_append, libname): # Test expected discovery methods based on environment if have_distribution_for(libname): assert found_header is not None - # When installed via pip wheel, should be found in site-packages assert found_header.found_via == "site-packages" hdr_dir_parts = found_header.abs_path.split(os.path.sep) assert "site-packages" in hdr_dir_parts elif STRICTNESS == "all_must_work": assert found_header is not None if conda_prefix := os.environ.get("CONDA_PREFIX"): - # When in conda environment, should be found via conda assert found_header.found_via == "conda" assert found_header.abs_path.startswith(conda_prefix) else: - # Otherwise should be found via system install (CUDA_HOME) assert found_header.found_via == "CUDA_HOME" inst_dirs = SUPPORTED_INSTALL_DIRS_NON_CTK.get(libname) if inst_dirs is not None: @@ -161,27 +156,25 @@ def test_find_non_ctk_headers_with_info(info_summary_append, libname): @pytest.mark.parametrize("libname", SUPPORTED_HEADERS_CTK.keys()) def test_find_ctk_headers_with_info(info_summary_append, libname): - """Test find_nvidia_header_directory_with_info for CTK libraries. + """Test locate_nvidia_header_directory for CTK libraries. This test validates: - 1. The function returns FoundHeader or None (not just a string) + 1. The function returns FoundHeaderDir or None (not just a string) 2. The abs_path matches what the original function returns 3. The found_via field correctly identifies the discovery method (site-packages, conda, or CUDA_HOME) """ - found_header = find_nvidia_header_directory(libname, include_info=True) - hdr_dir_original = find_nvidia_header_directory(libname, include_info=False) + found_header = locate_nvidia_header_directory(libname) + hdr_dir_original = find_nvidia_header_directory(libname) info_summary_append(f"{found_header=!r}") - # Test consistency between old and new API if found_header: - assert isinstance(found_header, FoundHeader) + assert isinstance(found_header, FoundHeaderDir) assert found_header.abs_path == hdr_dir_original assert os.path.isdir(found_header.abs_path) h_filename = SUPPORTED_HEADERS_CTK[libname] assert os.path.isfile(os.path.join(found_header.abs_path, h_filename)) - # Validate found_via field assert found_header.found_via in ("site-packages", "conda", "CUDA_HOME") info_summary_append(f"found_via={found_header.found_via!r}") else: From d5e1abe4b9eebd10816df5b2baa0b9f88b988be8 Mon Sep 17 00:00:00 2001 From: brandon-b-miller Date: Fri, 30 Jan 2026 07:11:03 -0800 Subject: [PATCH 5/7] test updates --- .../tests/test_find_nvidia_headers.py | 146 ++++-------------- 1 file changed, 31 insertions(+), 115 deletions(-) diff --git a/cuda_pathfinder/tests/test_find_nvidia_headers.py b/cuda_pathfinder/tests/test_find_nvidia_headers.py index 6a650d7963..8ab01a272c 100644 --- a/cuda_pathfinder/tests/test_find_nvidia_headers.py +++ b/cuda_pathfinder/tests/test_find_nvidia_headers.py @@ -19,8 +19,7 @@ import pytest -from cuda.pathfinder import find_nvidia_header_directory, locate_nvidia_header_directory -from cuda.pathfinder._headers.find_nvidia_headers import FoundHeaderDir +from cuda.pathfinder import FoundHeaderDir, find_nvidia_header_directory, locate_nvidia_header_directory from cuda.pathfinder._headers.supported_nvidia_headers import ( SUPPORTED_HEADERS_CTK, SUPPORTED_HEADERS_CTK_ALL, @@ -59,29 +58,35 @@ def have_distribution_for(libname: str) -> bool: @pytest.mark.parametrize("libname", SUPPORTED_HEADERS_NON_CTK.keys()) -def test_find_non_ctk_headers(info_summary_append, libname): - hdr_dir = find_nvidia_header_directory(libname) - info_summary_append(f"{hdr_dir=!r}") - if hdr_dir: - assert os.path.isdir(hdr_dir) - assert os.path.isfile(os.path.join(hdr_dir, SUPPORTED_HEADERS_NON_CTK[libname])) +def test_locate_non_ctk_headers(info_summary_append, libname): + found_header_dir = locate_nvidia_header_directory(libname) + info_summary_append(f"{None if not found_header_dir else found_header_dir.abs_path=!r}") + if found_header_dir: + assert isinstance(found_header_dir, FoundHeaderDir) + assert found_header_dir.found_via in ("site-packages", "conda", "CUDA_HOME") + # old api + hdr_dir = find_nvidia_header_directory(libname) + assert hdr_dir == found_header_dir.abs_path + + assert os.path.isdir(found_header_dir.abs_path) + assert os.path.isfile(os.path.join(found_header_dir.abs_path, SUPPORTED_HEADERS_NON_CTK[libname])) if have_distribution_for(libname): - assert hdr_dir is not None - hdr_dir_parts = hdr_dir.split(os.path.sep) - assert "site-packages" in hdr_dir_parts + assert found_header_dir.abs_path is not None + found_header_dir_parts = found_header_dir.abs_path.split(os.path.sep) + assert "site-packages" in found_header_dir_parts elif STRICTNESS == "all_must_work": - assert hdr_dir is not None + assert found_header_dir is not None if conda_prefix := os.environ.get("CONDA_PREFIX"): - assert hdr_dir.startswith(conda_prefix) + assert found_header_dir.abs_path.startswith(conda_prefix) else: inst_dirs = SUPPORTED_INSTALL_DIRS_NON_CTK.get(libname) if inst_dirs is not None: for inst_dir in inst_dirs: globbed = glob.glob(inst_dir) - if hdr_dir in globbed: + if found_header_dir.abs_path in globbed: break else: - raise RuntimeError(f"{hdr_dir=} does not match any {inst_dirs=}") + raise RuntimeError(f"{found_header_dir.abs_path=} does not match any {inst_dirs=}") def test_supported_headers_site_packages_ctk_consistency(): @@ -89,105 +94,16 @@ def test_supported_headers_site_packages_ctk_consistency(): @pytest.mark.parametrize("libname", SUPPORTED_HEADERS_CTK.keys()) -def test_find_ctk_headers(info_summary_append, libname): - hdr_dir = find_nvidia_header_directory(libname) - info_summary_append(f"{hdr_dir=!r}") - if hdr_dir: - assert os.path.isdir(hdr_dir) +def test_locate_ctk_headers(info_summary_append, libname): + found_header_dir = locate_nvidia_header_directory(libname) + info_summary_append(f"{None if not found_header_dir else found_header_dir.abs_path=!r}") + if found_header_dir: + # old api + hdr_dir = find_nvidia_header_directory(libname) + assert hdr_dir == found_header_dir.abs_path + + assert os.path.isdir(found_header_dir.abs_path) h_filename = SUPPORTED_HEADERS_CTK[libname] - assert os.path.isfile(os.path.join(hdr_dir, h_filename)) + assert os.path.isfile(os.path.join(found_header_dir.abs_path, h_filename)) if STRICTNESS == "all_must_work": - assert hdr_dir is not None - - -def test_unknown_libname_with_info(): - """Test that locate_nvidia_header_directory raises for unknown libraries.""" - with pytest.raises(RuntimeError, match=r"^UNKNOWN libname='unknown-libname'$"): - locate_nvidia_header_directory("unknown-libname") - - -@pytest.mark.parametrize("libname", SUPPORTED_HEADERS_NON_CTK.keys()) -def test_find_non_ctk_headers_with_info(info_summary_append, libname): - """Test find_nvidia_header_directory_with_info for non-CTK libraries. - - This test validates: - 1. The function returns FoundHeaderDir or None (not just a string) - 2. The abs_path matches what the original function returns - 3. The found_via field correctly identifies the discovery method - """ - found_header = find_nvidia_header_directory(libname) - hdr_dir_original = find_nvidia_header_directory(libname) - - info_summary_append(f"{found_header=!r}") - - if found_header: - assert isinstance(found_header, FoundHeaderDir) - assert found_header.abs_path == hdr_dir_original - assert os.path.isdir(found_header.abs_path) - assert os.path.isfile(os.path.join(found_header.abs_path, SUPPORTED_HEADERS_NON_CTK[libname])) - - assert found_header.found_via in ("site-packages", "conda", "CUDA_HOME") - info_summary_append(f"found_via={found_header.found_via!r}") - else: - assert hdr_dir_original is None - - # Test expected discovery methods based on environment - if have_distribution_for(libname): - assert found_header is not None - assert found_header.found_via == "site-packages" - hdr_dir_parts = found_header.abs_path.split(os.path.sep) - assert "site-packages" in hdr_dir_parts - elif STRICTNESS == "all_must_work": - assert found_header is not None - if conda_prefix := os.environ.get("CONDA_PREFIX"): - assert found_header.found_via == "conda" - assert found_header.abs_path.startswith(conda_prefix) - else: - assert found_header.found_via == "CUDA_HOME" - inst_dirs = SUPPORTED_INSTALL_DIRS_NON_CTK.get(libname) - if inst_dirs is not None: - for inst_dir in inst_dirs: - globbed = glob.glob(inst_dir) - if found_header.abs_path in globbed: - break - else: - raise RuntimeError(f"{found_header.abs_path=} does not match any {inst_dirs=}") - - -@pytest.mark.parametrize("libname", SUPPORTED_HEADERS_CTK.keys()) -def test_find_ctk_headers_with_info(info_summary_append, libname): - """Test locate_nvidia_header_directory for CTK libraries. - - This test validates: - 1. The function returns FoundHeaderDir or None (not just a string) - 2. The abs_path matches what the original function returns - 3. The found_via field correctly identifies the discovery method (site-packages, conda, or CUDA_HOME) - """ - found_header = locate_nvidia_header_directory(libname) - hdr_dir_original = find_nvidia_header_directory(libname) - - info_summary_append(f"{found_header=!r}") - - if found_header: - assert isinstance(found_header, FoundHeaderDir) - assert found_header.abs_path == hdr_dir_original - assert os.path.isdir(found_header.abs_path) - h_filename = SUPPORTED_HEADERS_CTK[libname] - assert os.path.isfile(os.path.join(found_header.abs_path, h_filename)) - - assert found_header.found_via in ("site-packages", "conda", "CUDA_HOME") - info_summary_append(f"found_via={found_header.found_via!r}") - else: - assert hdr_dir_original is None - - if STRICTNESS == "all_must_work": - assert found_header is not None - # In CI, CTK headers can come from: - # - site-packages wheels (when LOCAL_CTK=0 and extra wheels installed) - # - CUDA_HOME (when LOCAL_CTK=1 and mini CTK is set up) - # - conda (when CONDA_PREFIX is set) - - if os.environ.get("CONDA_PREFIX"): - assert found_header.found_via == "conda" - elif os.environ.get("CUDA_HOME") or os.environ.get("CUDA_PATH"): - assert found_header.found_via == "CUDA_HOME" + assert found_header_dir.abs_path is not None From fde70b161f6d7c0b72ac0eeefd2b2ae0794e718f Mon Sep 17 00:00:00 2001 From: brandon-b-miller Date: Fri, 30 Jan 2026 11:19:30 -0800 Subject: [PATCH 6/7] address reviews --- cuda_pathfinder/cuda/pathfinder/__init__.py | 2 +- .../_headers/find_nvidia_headers.py | 30 +++++----- .../tests/test_find_nvidia_headers.py | 56 +++++++++---------- 3 files changed, 43 insertions(+), 45 deletions(-) diff --git a/cuda_pathfinder/cuda/pathfinder/__init__.py b/cuda_pathfinder/cuda/pathfinder/__init__.py index e905a839c5..4ff5035b44 100644 --- a/cuda_pathfinder/cuda/pathfinder/__init__.py +++ b/cuda_pathfinder/cuda/pathfinder/__init__.py @@ -9,7 +9,7 @@ from cuda.pathfinder._dynamic_libs.supported_nvidia_libs import ( SUPPORTED_LIBNAMES as SUPPORTED_NVIDIA_LIBNAMES, # noqa: F401 ) -from cuda.pathfinder._headers.find_nvidia_headers import FoundHeaderDir as FoundHeaderDir +from cuda.pathfinder._headers.find_nvidia_headers import LocatedHeaderDir as LocatedHeaderDir from cuda.pathfinder._headers.find_nvidia_headers import find_nvidia_header_directory as find_nvidia_header_directory from cuda.pathfinder._headers.find_nvidia_headers import ( locate_nvidia_header_directory as locate_nvidia_header_directory, diff --git a/cuda_pathfinder/cuda/pathfinder/_headers/find_nvidia_headers.py b/cuda_pathfinder/cuda/pathfinder/_headers/find_nvidia_headers.py index 3039cf208d..637ecabfcb 100644 --- a/cuda_pathfinder/cuda/pathfinder/_headers/find_nvidia_headers.py +++ b/cuda_pathfinder/cuda/pathfinder/_headers/find_nvidia_headers.py @@ -15,7 +15,7 @@ @dataclass -class FoundHeaderDir: +class LocatedHeaderDir: abs_path: str | None found_via: str @@ -33,16 +33,16 @@ def _joined_isfile(dirpath: str, basename: str) -> bool: return os.path.isfile(os.path.join(dirpath, basename)) -def _find_under_site_packages(sub_dir: str, h_basename: str) -> FoundHeaderDir | None: +def _locate_under_site_packages(sub_dir: str, h_basename: str) -> LocatedHeaderDir | None: # Installed from a wheel hdr_dir: str # help mypy for hdr_dir in find_sub_dirs_all_sitepackages(tuple(sub_dir.split("/"))): if _joined_isfile(hdr_dir, h_basename): - return FoundHeaderDir(abs_path=hdr_dir, found_via="site-packages") + return LocatedHeaderDir(abs_path=hdr_dir, found_via="site-packages") return None -def _find_based_on_ctk_layout(libname: str, h_basename: str, anchor_point: str) -> str | None: +def _locate_based_on_ctk_layout(libname: str, h_basename: str, anchor_point: str) -> str | None: parts = [anchor_point] if libname == "nvvm": parts.append(libname) @@ -64,7 +64,7 @@ def _find_based_on_ctk_layout(libname: str, h_basename: str, anchor_point: str) return None -def _find_based_on_conda_layout(libname: str, h_basename: str, ctk_layout: bool) -> FoundHeaderDir | None: +def _find_based_on_conda_layout(libname: str, h_basename: str, ctk_layout: bool) -> LocatedHeaderDir | None: conda_prefix = os.environ.get("CONDA_PREFIX") if not conda_prefix: return None @@ -85,18 +85,18 @@ def _find_based_on_conda_layout(libname: str, h_basename: str, ctk_layout: bool) else: include_path = os.path.join(conda_prefix, "include") anchor_point = os.path.dirname(include_path) - found_header_path = _find_based_on_ctk_layout(libname, h_basename, anchor_point) + found_header_path = _locate_based_on_ctk_layout(libname, h_basename, anchor_point) if found_header_path: - return FoundHeaderDir(abs_path=found_header_path, found_via="conda") + return LocatedHeaderDir(abs_path=found_header_path, found_via="conda") return None -def _find_ctk_header_directory(libname: str) -> FoundHeaderDir | None: +def _find_ctk_header_directory(libname: str) -> LocatedHeaderDir | None: h_basename = supported_nvidia_headers.SUPPORTED_HEADERS_CTK[libname] candidate_dirs = supported_nvidia_headers.SUPPORTED_SITE_PACKAGE_HEADER_DIRS_CTK[libname] for cdir in candidate_dirs: - if hdr_dir := _find_under_site_packages(cdir, h_basename): + if hdr_dir := _locate_under_site_packages(cdir, h_basename): return hdr_dir if hdr_dir := _find_based_on_conda_layout(libname, h_basename, True): @@ -104,14 +104,14 @@ def _find_ctk_header_directory(libname: str) -> FoundHeaderDir | None: cuda_home = get_cuda_home_or_path() if cuda_home: # noqa: SIM102 - if result := _find_based_on_ctk_layout(libname, h_basename, cuda_home): - return FoundHeaderDir(abs_path=result, found_via="CUDA_HOME") + if result := _locate_based_on_ctk_layout(libname, h_basename, cuda_home): + return LocatedHeaderDir(abs_path=result, found_via="CUDA_HOME") return None @functools.cache -def locate_nvidia_header_directory(libname: str) -> FoundHeaderDir | None: +def locate_nvidia_header_directory(libname: str) -> LocatedHeaderDir | None: """Locate the header directory for a supported NVIDIA library. Args: @@ -119,7 +119,7 @@ def locate_nvidia_header_directory(libname: str) -> FoundHeaderDir | None: (e.g., ``"nvrtc"``, ``"cusolver"``, ``"nvshmem"``). Returns: - FoundHeaderDir or None: A FoundHeaderDir object containing the absolute path + LocatedHeaderDir or None: A LocatedHeaderDir object containing the absolute path to the discovered header directory and information about where it was found, or ``None`` if the headers cannot be found. @@ -152,7 +152,7 @@ def locate_nvidia_header_directory(libname: str) -> FoundHeaderDir | None: candidate_dirs = supported_nvidia_headers.SUPPORTED_SITE_PACKAGE_HEADER_DIRS_NON_CTK.get(libname, []) for cdir in candidate_dirs: - if found_hdr := _find_under_site_packages(cdir, h_basename): + if found_hdr := _locate_under_site_packages(cdir, h_basename): return found_hdr if found_hdr := _find_based_on_conda_layout(libname, h_basename, False): @@ -164,7 +164,7 @@ def locate_nvidia_header_directory(libname: str) -> FoundHeaderDir | None: for hdr_dir in sorted(glob.glob(cdir), reverse=True): if _joined_isfile(hdr_dir, h_basename): # For system installs, we don't have a clear found_via, so use "system" - return FoundHeaderDir(abs_path=hdr_dir, found_via="supported_install_dir") + return LocatedHeaderDir(abs_path=hdr_dir, found_via="supported_install_dir") return None diff --git a/cuda_pathfinder/tests/test_find_nvidia_headers.py b/cuda_pathfinder/tests/test_find_nvidia_headers.py index 8ab01a272c..1a362b03d6 100644 --- a/cuda_pathfinder/tests/test_find_nvidia_headers.py +++ b/cuda_pathfinder/tests/test_find_nvidia_headers.py @@ -19,7 +19,7 @@ import pytest -from cuda.pathfinder import FoundHeaderDir, find_nvidia_header_directory, locate_nvidia_header_directory +from cuda.pathfinder import LocatedHeaderDir, find_nvidia_header_directory, locate_nvidia_header_directory from cuda.pathfinder._headers.supported_nvidia_headers import ( SUPPORTED_HEADERS_CTK, SUPPORTED_HEADERS_CTK_ALL, @@ -59,34 +59,33 @@ def have_distribution_for(libname: str) -> bool: @pytest.mark.parametrize("libname", SUPPORTED_HEADERS_NON_CTK.keys()) def test_locate_non_ctk_headers(info_summary_append, libname): - found_header_dir = locate_nvidia_header_directory(libname) - info_summary_append(f"{None if not found_header_dir else found_header_dir.abs_path=!r}") - if found_header_dir: - assert isinstance(found_header_dir, FoundHeaderDir) - assert found_header_dir.found_via in ("site-packages", "conda", "CUDA_HOME") - # old api - hdr_dir = find_nvidia_header_directory(libname) - assert hdr_dir == found_header_dir.abs_path - - assert os.path.isdir(found_header_dir.abs_path) - assert os.path.isfile(os.path.join(found_header_dir.abs_path, SUPPORTED_HEADERS_NON_CTK[libname])) + hdr_dir = find_nvidia_header_directory(libname) + located_hdr_dir = locate_nvidia_header_directory(libname) + assert hdr_dir is None if not located_hdr_dir else hdr_dir == located_hdr_dir.abs_path + + info_summary_append(f"{hdr_dir=!r}") + if hdr_dir: + assert isinstance(located_hdr_dir, LocatedHeaderDir) + assert located_hdr_dir.found_via in ("site-packages", "conda", "CUDA_HOME") + assert os.path.isdir(hdr_dir) + assert os.path.isfile(os.path.join(hdr_dir, SUPPORTED_HEADERS_NON_CTK[libname])) if have_distribution_for(libname): - assert found_header_dir.abs_path is not None - found_header_dir_parts = found_header_dir.abs_path.split(os.path.sep) - assert "site-packages" in found_header_dir_parts + assert hdr_dir is not None + hdr_dir_parts = hdr_dir.split(os.path.sep) + assert "site-packages" in hdr_dir_parts elif STRICTNESS == "all_must_work": - assert found_header_dir is not None + assert hdr_dir is not None if conda_prefix := os.environ.get("CONDA_PREFIX"): - assert found_header_dir.abs_path.startswith(conda_prefix) + assert hdr_dir.startswith(conda_prefix) else: inst_dirs = SUPPORTED_INSTALL_DIRS_NON_CTK.get(libname) if inst_dirs is not None: for inst_dir in inst_dirs: globbed = glob.glob(inst_dir) - if found_header_dir.abs_path in globbed: + if hdr_dir in globbed: break else: - raise RuntimeError(f"{found_header_dir.abs_path=} does not match any {inst_dirs=}") + raise RuntimeError(f"{hdr_dir=} does not match any {inst_dirs=}") def test_supported_headers_site_packages_ctk_consistency(): @@ -95,15 +94,14 @@ def test_supported_headers_site_packages_ctk_consistency(): @pytest.mark.parametrize("libname", SUPPORTED_HEADERS_CTK.keys()) def test_locate_ctk_headers(info_summary_append, libname): - found_header_dir = locate_nvidia_header_directory(libname) - info_summary_append(f"{None if not found_header_dir else found_header_dir.abs_path=!r}") - if found_header_dir: - # old api - hdr_dir = find_nvidia_header_directory(libname) - assert hdr_dir == found_header_dir.abs_path - - assert os.path.isdir(found_header_dir.abs_path) + hdr_dir = find_nvidia_header_directory(libname) + located_hdr_dir = locate_nvidia_header_directory(libname) + assert hdr_dir is None if not located_hdr_dir else hdr_dir == located_hdr_dir.abs_path + + info_summary_append(f"{hdr_dir=!r}") + if hdr_dir: + assert os.path.isdir(hdr_dir) h_filename = SUPPORTED_HEADERS_CTK[libname] - assert os.path.isfile(os.path.join(found_header_dir.abs_path, h_filename)) + assert os.path.isfile(os.path.join(hdr_dir, h_filename)) if STRICTNESS == "all_must_work": - assert found_header_dir.abs_path is not None + assert hdr_dir is not None From c9018833b6ee4d61612bc017bc36c64795bfcf0e Mon Sep 17 00:00:00 2001 From: brandon-b-miller Date: Fri, 30 Jan 2026 12:35:27 -0800 Subject: [PATCH 7/7] address reviews --- cuda_pathfinder/tests/test_find_nvidia_headers.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/cuda_pathfinder/tests/test_find_nvidia_headers.py b/cuda_pathfinder/tests/test_find_nvidia_headers.py index 1a362b03d6..f14681546d 100644 --- a/cuda_pathfinder/tests/test_find_nvidia_headers.py +++ b/cuda_pathfinder/tests/test_find_nvidia_headers.py @@ -44,6 +44,11 @@ def test_unknown_libname(): find_nvidia_header_directory("unknown-libname") +def _located_hdr_dir_asserts(located_hdr_dir): + assert isinstance(located_hdr_dir, LocatedHeaderDir) + assert located_hdr_dir.found_via in ("site-packages", "conda", "CUDA_HOME", "supported_install_dir") + + def test_non_ctk_importlib_metadata_distributions_names(): # Ensure the dict keys above stay in sync with supported_nvidia_headers assert sorted(NON_CTK_IMPORTLIB_METADATA_DISTRIBUTIONS_NAMES) == sorted(SUPPORTED_HEADERS_NON_CTK_ALL) @@ -65,8 +70,7 @@ def test_locate_non_ctk_headers(info_summary_append, libname): info_summary_append(f"{hdr_dir=!r}") if hdr_dir: - assert isinstance(located_hdr_dir, LocatedHeaderDir) - assert located_hdr_dir.found_via in ("site-packages", "conda", "CUDA_HOME") + _located_hdr_dir_asserts(located_hdr_dir) assert os.path.isdir(hdr_dir) assert os.path.isfile(os.path.join(hdr_dir, SUPPORTED_HEADERS_NON_CTK[libname])) if have_distribution_for(libname): @@ -100,6 +104,7 @@ def test_locate_ctk_headers(info_summary_append, libname): info_summary_append(f"{hdr_dir=!r}") if hdr_dir: + _located_hdr_dir_asserts(located_hdr_dir) assert os.path.isdir(hdr_dir) h_filename = SUPPORTED_HEADERS_CTK[libname] assert os.path.isfile(os.path.join(hdr_dir, h_filename))