From d874a168b64d4f5432ddcf59205cf5d30d98685c Mon Sep 17 00:00:00 2001 From: LeSingh1 Date: Mon, 3 Aug 2026 23:41:21 -0700 Subject: [PATCH 1/2] Migrate _static_libs finders from os.path to pathlib Part 2 of the series proposed in #2410, following the same conversion style as part 1 (#2489). Path construction, joining, and filesystem predicates in find_static_lib.py and find_bitcode_lib.py now go through pathlib.Path instead of os.path string manipulation. Both modules keep importing os solely for os.environ.get("CONDA_PREFIX"). Compatibility is preserved: every entry point still accepts str, and every function that documents or returns str still returns str. Path is used strictly as the internal representation and converted back with str() at each return, so LocatedStaticLib.abs_path, LocatedBitcodeLib .abs_path, find_static_lib() and find_bitcode_lib() are unchanged in both type and value. No signature changes. Signed-off-by: LeSingh1 --- .../_static_libs/find_bitcode_lib.py | 33 +++++++++-------- .../_static_libs/find_static_lib.py | 35 ++++++++++--------- 2 files changed, 37 insertions(+), 31 deletions(-) diff --git a/cuda_pathfinder/cuda/pathfinder/_static_libs/find_bitcode_lib.py b/cuda_pathfinder/cuda/pathfinder/_static_libs/find_bitcode_lib.py index ac038aadfe7..97db7bef0a0 100644 --- a/cuda_pathfinder/cuda/pathfinder/_static_libs/find_bitcode_lib.py +++ b/cuda_pathfinder/cuda/pathfinder/_static_libs/find_bitcode_lib.py @@ -4,6 +4,7 @@ import functools import os from dataclasses import dataclass +from pathlib import Path from typing import NoReturn, TypedDict from cuda.pathfinder._utils.env_vars import get_cuda_path_or_home @@ -35,7 +36,7 @@ class _BitcodeLibInfo(TypedDict): _SUPPORTED_BITCODE_LIBS_INFO: dict[str, _BitcodeLibInfo] = { "device": { "filename": "libdevice.10.bc", - "rel_path": os.path.join("nvvm", "libdevice"), + "rel_path": str(Path("nvvm", "libdevice")), "site_packages_dirs": ( "nvidia/cu13/nvvm/libdevice", "nvidia/cuda_nvcc/nvvm/libdevice", @@ -65,10 +66,11 @@ class _BitcodeLibInfo(TypedDict): def _no_such_file_in_dir(dir_path: str, filename: str, error_messages: list[str], attachments: list[str]) -> None: - error_messages.append(f"No such file: {os.path.join(dir_path, filename)}") - if os.path.isdir(dir_path): + directory = Path(dir_path) + error_messages.append(f"No such file: {directory / filename}") + if directory.is_dir(): attachments.append(f' listdir("{dir_path}"):') - for node in sorted(os.listdir(dir_path)): + for node in sorted(node_path.name for node_path in directory.iterdir()): attachments.append(f" {node}") else: attachments.append(f' Directory does not exist: "{dir_path}"') @@ -90,9 +92,9 @@ def try_site_packages(self) -> str | None: for rel_dir in self.site_packages_dirs: sub_dir = tuple(rel_dir.split("/")) for abs_dir in find_sub_dirs_all_sitepackages(sub_dir): - file_path = os.path.join(abs_dir, self.filename) - if os.path.isfile(file_path): - return file_path + file_path = Path(abs_dir, self.filename) + if file_path.is_file(): + return str(file_path) return None def try_with_conda_prefix(self) -> str | None: @@ -100,10 +102,10 @@ def try_with_conda_prefix(self) -> str | None: if not conda_prefix: return None - anchor = os.path.join(conda_prefix, "Library") if IS_WINDOWS else conda_prefix - file_path = os.path.join(anchor, self.rel_path, self.filename) - if os.path.isfile(file_path): - return file_path + anchor = Path(conda_prefix, "Library") if IS_WINDOWS else Path(conda_prefix) + file_path = anchor / self.rel_path / self.filename + if file_path.is_file(): + return str(file_path) return None def try_with_cuda_home(self) -> str | None: @@ -112,12 +114,13 @@ def try_with_cuda_home(self) -> str | None: self.error_messages.append("CUDA_HOME/CUDA_PATH not set") return None - file_path = os.path.join(cuda_home, self.rel_path, self.filename) - if os.path.isfile(file_path): - return file_path + cuda_home_path = Path(cuda_home) + file_path = cuda_home_path / self.rel_path / self.filename + if file_path.is_file(): + return str(file_path) _no_such_file_in_dir( - os.path.join(cuda_home, self.rel_path), + str(cuda_home_path / self.rel_path), self.filename, self.error_messages, self.attachments, diff --git a/cuda_pathfinder/cuda/pathfinder/_static_libs/find_static_lib.py b/cuda_pathfinder/cuda/pathfinder/_static_libs/find_static_lib.py index 804b1c04be7..4a00edb3592 100644 --- a/cuda_pathfinder/cuda/pathfinder/_static_libs/find_static_lib.py +++ b/cuda_pathfinder/cuda/pathfinder/_static_libs/find_static_lib.py @@ -4,6 +4,7 @@ import functools import os from dataclasses import dataclass +from pathlib import Path from typing import NoReturn, TypedDict from cuda.pathfinder._utils.env_vars import get_cuda_path_or_home @@ -35,8 +36,8 @@ class _StaticLibInfo(TypedDict): _SUPPORTED_STATIC_LIBS_INFO: dict[str, _StaticLibInfo] = { "cudadevrt": { "filename": "cudadevrt.lib" if IS_WINDOWS else "libcudadevrt.a", - "ctk_rel_paths": (os.path.join("lib", "x64"),) if IS_WINDOWS else ("lib64", "lib"), - "conda_rel_paths": ((os.path.join("lib", "x64"), "lib") if IS_WINDOWS else ("lib",)), + "ctk_rel_paths": (str(Path("lib", "x64")),) if IS_WINDOWS else ("lib64", "lib"), + "conda_rel_paths": ((str(Path("lib", "x64")), "lib") if IS_WINDOWS else ("lib",)), "site_packages_dirs": ( ("nvidia/cu13/lib/x64", "nvidia/cuda_runtime/lib/x64") if IS_WINDOWS @@ -49,10 +50,11 @@ class _StaticLibInfo(TypedDict): def _no_such_file_in_dir(dir_path: str, filename: str, error_messages: list[str], attachments: list[str]) -> None: - error_messages.append(f"No such file: {os.path.join(dir_path, filename)}") - if os.path.isdir(dir_path): + directory = Path(dir_path) + error_messages.append(f"No such file: {directory / filename}") + if directory.is_dir(): attachments.append(f' listdir("{dir_path}"):') - for node in sorted(os.listdir(dir_path)): + for node in sorted(node_path.name for node_path in directory.iterdir()): attachments.append(f" {node}") else: attachments.append(f' Directory does not exist: "{dir_path}"') @@ -75,9 +77,9 @@ def try_site_packages(self) -> str | None: for rel_dir in self.site_packages_dirs: sub_dir = tuple(rel_dir.split("/")) for abs_dir in find_sub_dirs_all_sitepackages(sub_dir): - file_path = os.path.join(abs_dir, self.filename) - if os.path.isfile(file_path): - return file_path + file_path = Path(abs_dir, self.filename) + if file_path.is_file(): + return str(file_path) return None def try_with_conda_prefix(self) -> str | None: @@ -85,11 +87,11 @@ def try_with_conda_prefix(self) -> str | None: if not conda_prefix: return None - anchor = os.path.join(conda_prefix, "Library") if IS_WINDOWS else conda_prefix + anchor = Path(conda_prefix, "Library") if IS_WINDOWS else Path(conda_prefix) for rel_path in self.conda_rel_paths: - file_path = os.path.join(anchor, rel_path, self.filename) - if os.path.isfile(file_path): - return file_path + file_path = anchor / rel_path / self.filename + if file_path.is_file(): + return str(file_path) return None def try_with_cuda_home(self) -> str | None: @@ -98,13 +100,14 @@ def try_with_cuda_home(self) -> str | None: self.error_messages.append("CUDA_HOME/CUDA_PATH not set") return None + cuda_home_path = Path(cuda_home) for rel_path in self.ctk_rel_paths: - file_path = os.path.join(cuda_home, rel_path, self.filename) - if os.path.isfile(file_path): - return file_path + file_path = cuda_home_path / rel_path / self.filename + if file_path.is_file(): + return str(file_path) _no_such_file_in_dir( - os.path.join(cuda_home, self.ctk_rel_paths[0]), + str(cuda_home_path / self.ctk_rel_paths[0]), self.filename, self.error_messages, self.attachments, From 8ed361d502d4b7c279dbe618e66f3b5e98892b24 Mon Sep 17 00:00:00 2001 From: LeSingh1 Date: Tue, 4 Aug 2026 12:53:55 -0700 Subject: [PATCH 2/2] Return Path from the _static_libs internals Follow-up to the review feedback on #2489: the str-compatibility constraint applies only to the public API. The try_* methods and _no_such_file_in_dir now work in Path throughout. str() is applied once, where abs_path is stored on the public LocatedStaticLib and LocatedBitcodeLib. The relative-path constants go from os.path.join(...) to forward-slash literals, matching how site_packages_dirs is already written in the same dicts; Path normalizes the separator on Windows. One behavior change: a CUDA_PATH or CONDA_PREFIX containing redundant separators ("//", "/.") now produces a normalized abs_path, because Path collapses them. Differential fuzzing against the pre-revision code (16k lookups over randomized trees, comparing located paths and full error text) shows no other difference, and none at all when those variables are free of redundant separators. Signed-off-by: LeSingh1 --- .../_static_libs/find_bitcode_lib.py | 33 +++++++++-------- .../_static_libs/find_static_lib.py | 35 +++++++++---------- 2 files changed, 33 insertions(+), 35 deletions(-) diff --git a/cuda_pathfinder/cuda/pathfinder/_static_libs/find_bitcode_lib.py b/cuda_pathfinder/cuda/pathfinder/_static_libs/find_bitcode_lib.py index 97db7bef0a0..803abecaaae 100644 --- a/cuda_pathfinder/cuda/pathfinder/_static_libs/find_bitcode_lib.py +++ b/cuda_pathfinder/cuda/pathfinder/_static_libs/find_bitcode_lib.py @@ -36,7 +36,7 @@ class _BitcodeLibInfo(TypedDict): _SUPPORTED_BITCODE_LIBS_INFO: dict[str, _BitcodeLibInfo] = { "device": { "filename": "libdevice.10.bc", - "rel_path": str(Path("nvvm", "libdevice")), + "rel_path": "nvvm/libdevice", "site_packages_dirs": ( "nvidia/cu13/nvvm/libdevice", "nvidia/cuda_nvcc/nvvm/libdevice", @@ -65,15 +65,14 @@ class _BitcodeLibInfo(TypedDict): ) -def _no_such_file_in_dir(dir_path: str, filename: str, error_messages: list[str], attachments: list[str]) -> None: - directory = Path(dir_path) +def _no_such_file_in_dir(directory: Path, filename: str, error_messages: list[str], attachments: list[str]) -> None: error_messages.append(f"No such file: {directory / filename}") if directory.is_dir(): - attachments.append(f' listdir("{dir_path}"):') + attachments.append(f' listdir("{directory}"):') for node in sorted(node_path.name for node_path in directory.iterdir()): attachments.append(f" {node}") else: - attachments.append(f' Directory does not exist: "{dir_path}"') + attachments.append(f' Directory does not exist: "{directory}"') class _FindBitcodeLib: @@ -88,16 +87,16 @@ def __init__(self, name: str) -> None: self.error_messages: list[str] = [] self.attachments: list[str] = [] - def try_site_packages(self) -> str | None: + def try_site_packages(self) -> Path | None: for rel_dir in self.site_packages_dirs: sub_dir = tuple(rel_dir.split("/")) for abs_dir in find_sub_dirs_all_sitepackages(sub_dir): file_path = Path(abs_dir, self.filename) if file_path.is_file(): - return str(file_path) + return file_path return None - def try_with_conda_prefix(self) -> str | None: + def try_with_conda_prefix(self) -> Path | None: conda_prefix = os.environ.get("CONDA_PREFIX") if not conda_prefix: return None @@ -105,22 +104,22 @@ def try_with_conda_prefix(self) -> str | None: anchor = Path(conda_prefix, "Library") if IS_WINDOWS else Path(conda_prefix) file_path = anchor / self.rel_path / self.filename if file_path.is_file(): - return str(file_path) + return file_path return None - def try_with_cuda_home(self) -> str | None: + def try_with_cuda_home(self) -> Path | None: cuda_home = get_cuda_path_or_home() if cuda_home is None: self.error_messages.append("CUDA_HOME/CUDA_PATH not set") return None - cuda_home_path = Path(cuda_home) - file_path = cuda_home_path / self.rel_path / self.filename + anchor = Path(cuda_home) + file_path = anchor / self.rel_path / self.filename if file_path.is_file(): - return str(file_path) + return file_path _no_such_file_in_dir( - str(cuda_home_path / self.rel_path), + anchor / self.rel_path, self.filename, self.error_messages, self.attachments, @@ -146,7 +145,7 @@ def locate_bitcode_lib(name: str) -> LocatedBitcodeLib: if abs_path is not None: return LocatedBitcodeLib( name=name, - abs_path=abs_path, + abs_path=str(abs_path), filename=finder.filename, found_via="site-packages", ) @@ -155,7 +154,7 @@ def locate_bitcode_lib(name: str) -> LocatedBitcodeLib: if abs_path is not None: return LocatedBitcodeLib( name=name, - abs_path=abs_path, + abs_path=str(abs_path), filename=finder.filename, found_via="conda", ) @@ -164,7 +163,7 @@ def locate_bitcode_lib(name: str) -> LocatedBitcodeLib: if abs_path is not None: return LocatedBitcodeLib( name=name, - abs_path=abs_path, + abs_path=str(abs_path), filename=finder.filename, found_via="CUDA_PATH", ) diff --git a/cuda_pathfinder/cuda/pathfinder/_static_libs/find_static_lib.py b/cuda_pathfinder/cuda/pathfinder/_static_libs/find_static_lib.py index 4a00edb3592..6d2e936c819 100644 --- a/cuda_pathfinder/cuda/pathfinder/_static_libs/find_static_lib.py +++ b/cuda_pathfinder/cuda/pathfinder/_static_libs/find_static_lib.py @@ -36,8 +36,8 @@ class _StaticLibInfo(TypedDict): _SUPPORTED_STATIC_LIBS_INFO: dict[str, _StaticLibInfo] = { "cudadevrt": { "filename": "cudadevrt.lib" if IS_WINDOWS else "libcudadevrt.a", - "ctk_rel_paths": (str(Path("lib", "x64")),) if IS_WINDOWS else ("lib64", "lib"), - "conda_rel_paths": ((str(Path("lib", "x64")), "lib") if IS_WINDOWS else ("lib",)), + "ctk_rel_paths": ("lib/x64",) if IS_WINDOWS else ("lib64", "lib"), + "conda_rel_paths": (("lib/x64", "lib") if IS_WINDOWS else ("lib",)), "site_packages_dirs": ( ("nvidia/cu13/lib/x64", "nvidia/cuda_runtime/lib/x64") if IS_WINDOWS @@ -49,15 +49,14 @@ class _StaticLibInfo(TypedDict): SUPPORTED_STATIC_LIBS: tuple[str, ...] = tuple(sorted(_SUPPORTED_STATIC_LIBS_INFO.keys())) -def _no_such_file_in_dir(dir_path: str, filename: str, error_messages: list[str], attachments: list[str]) -> None: - directory = Path(dir_path) +def _no_such_file_in_dir(directory: Path, filename: str, error_messages: list[str], attachments: list[str]) -> None: error_messages.append(f"No such file: {directory / filename}") if directory.is_dir(): - attachments.append(f' listdir("{dir_path}"):') + attachments.append(f' listdir("{directory}"):') for node in sorted(node_path.name for node_path in directory.iterdir()): attachments.append(f" {node}") else: - attachments.append(f' Directory does not exist: "{dir_path}"') + attachments.append(f' Directory does not exist: "{directory}"') class _FindStaticLib: @@ -73,16 +72,16 @@ def __init__(self, name: str) -> None: self.error_messages: list[str] = [] self.attachments: list[str] = [] - def try_site_packages(self) -> str | None: + def try_site_packages(self) -> Path | None: for rel_dir in self.site_packages_dirs: sub_dir = tuple(rel_dir.split("/")) for abs_dir in find_sub_dirs_all_sitepackages(sub_dir): file_path = Path(abs_dir, self.filename) if file_path.is_file(): - return str(file_path) + return file_path return None - def try_with_conda_prefix(self) -> str | None: + def try_with_conda_prefix(self) -> Path | None: conda_prefix = os.environ.get("CONDA_PREFIX") if not conda_prefix: return None @@ -91,23 +90,23 @@ def try_with_conda_prefix(self) -> str | None: for rel_path in self.conda_rel_paths: file_path = anchor / rel_path / self.filename if file_path.is_file(): - return str(file_path) + return file_path return None - def try_with_cuda_home(self) -> str | None: + def try_with_cuda_home(self) -> Path | None: cuda_home = get_cuda_path_or_home() if cuda_home is None: self.error_messages.append("CUDA_HOME/CUDA_PATH not set") return None - cuda_home_path = Path(cuda_home) + anchor = Path(cuda_home) for rel_path in self.ctk_rel_paths: - file_path = cuda_home_path / rel_path / self.filename + file_path = anchor / rel_path / self.filename if file_path.is_file(): - return str(file_path) + return file_path _no_such_file_in_dir( - str(cuda_home_path / self.ctk_rel_paths[0]), + anchor / self.ctk_rel_paths[0], self.filename, self.error_messages, self.attachments, @@ -133,7 +132,7 @@ def locate_static_lib(name: str) -> LocatedStaticLib: if abs_path is not None: return LocatedStaticLib( name=name, - abs_path=abs_path, + abs_path=str(abs_path), filename=finder.filename, found_via="site-packages", ) @@ -142,7 +141,7 @@ def locate_static_lib(name: str) -> LocatedStaticLib: if abs_path is not None: return LocatedStaticLib( name=name, - abs_path=abs_path, + abs_path=str(abs_path), filename=finder.filename, found_via="conda", ) @@ -151,7 +150,7 @@ def locate_static_lib(name: str) -> LocatedStaticLib: if abs_path is not None: return LocatedStaticLib( name=name, - abs_path=abs_path, + abs_path=str(abs_path), filename=finder.filename, found_via="CUDA_PATH", )