From d561a093fee1b420bf6b051768aae1a0d29894ff Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Tue, 10 Sep 2024 12:59:17 -0400 Subject: [PATCH 1/3] fix: support multiplexed path Co-authored-by: Cristian Le Signed-off-by: Henry Schreiner --- pyproject.toml | 1 + .../_compat/importlib/readers.py | 24 +++++++++++++++++++ src/scikit_build_core/builder/builder.py | 20 ++++++++++++++-- 3 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 src/scikit_build_core/_compat/importlib/readers.py diff --git a/pyproject.toml b/pyproject.toml index eb8d0ae1..8ee5c9c5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -296,6 +296,7 @@ known-local-folder = ["pathutils"] "importlib_metadata".msg = "Use scikit_build_core._compat.importlib.metadata instead." "importlib.resources".msg = "Use scikit_build_core._compat.importlib.resources instead." "importlib_resources".msg = "Use scikit_build_core._compat.importlib.resources instead." +"importlib.readers".msg = "Use scikit_build_core._compat.importlib.readers instead." "pyproject_metadata".msg = "Use scikit_build_core._vendor.pyproject_metadata instead." diff --git a/src/scikit_build_core/_compat/importlib/readers.py b/src/scikit_build_core/_compat/importlib/readers.py new file mode 100644 index 00000000..eb010349 --- /dev/null +++ b/src/scikit_build_core/_compat/importlib/readers.py @@ -0,0 +1,24 @@ +from __future__ import annotations + +import sys +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from pathlib import Path + +if sys.version_info < (3, 10): + # Readers and MultiplexedPath were introduced in 3.10, so nothing should output a MultiplexedPath + # It is also tricky because it is unclear if the `resource_loader` when calling `import` would create + # either importlib.readers.MultiplexedPath or importlib_resources.MultiplexedPath. + # Creating a dummy class instead so that if it fails, it fails completely (and mypy is made happy) + class MultiplexedPath: + _paths: list[Path] +else: + # From 3.11 this is an alias of importlib.resources.readers + from importlib.readers import MultiplexedPath + +__all__ = ["MultiplexedPath"] + + +def __dir__() -> list[str]: + return __all__ diff --git a/src/scikit_build_core/builder/builder.py b/src/scikit_build_core/builder/builder.py index acbe114c..f1ca53ac 100644 --- a/src/scikit_build_core/builder/builder.py +++ b/src/scikit_build_core/builder/builder.py @@ -10,6 +10,7 @@ from .. import __version__ from .._compat.importlib import metadata, resources +from .._compat.importlib.readers import MultiplexedPath from .._logging import logger from ..resources import find_python from .generator import set_environment_for_gen @@ -22,6 +23,7 @@ ) if TYPE_CHECKING: + import os from collections.abc import Generator, Iterable, Mapping, Sequence from packaging.version import Version @@ -84,6 +86,15 @@ def _filter_env_cmake_args(env_cmake_args: list[str]) -> Generator[str, None, No yield arg +# Type-hinting for Traversable is rather hard because they were introduced in python 3.11. +# This avoids introducing importlib_resources dependency that may not be used in the actual package loader +def _sanitize_path(path: os.PathLike[str]) -> list[Path]: + if isinstance(path, MultiplexedPath): + # pylint: disable-next=protected-access + return path._paths + return [Path(path)] + + @dataclasses.dataclass class Builder: settings: ScikitBuildSettings @@ -124,11 +135,15 @@ def configure( # Add any extra CMake modules eps = metadata.entry_points(group="cmake.module") - self.config.module_dirs.extend(resources.files(ep.load()) for ep in eps) + self.config.module_dirs.extend( + p for ep in eps for p in _sanitize_path(resources.files(ep.load())) + ) # Add any extra CMake prefixes eps = metadata.entry_points(group="cmake.prefix") - self.config.prefix_dirs.extend(resources.files(ep.load()) for ep in eps) + self.config.prefix_dirs.extend( + p for ep in eps for p in _sanitize_path(resources.files(ep.load())) + ) # Add site-packages to the prefix path for CMake site_packages = Path(sysconfig.get_path("purelib")) @@ -137,6 +152,7 @@ def configure( if site_packages != DIR.parent.parent: self.config.prefix_dirs.append(DIR.parent.parent) logger.debug("Extra SITE_PACKAGES: {}", DIR.parent.parent) + logger.debug("PATH: {}", sys.path) # Add the FindPython backport if needed if self.config.cmake.version < self.settings.backport.find_python: From 272a815825de49fa1eccad3655ee87f290a2d605 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Tue, 10 Sep 2024 14:08:19 -0400 Subject: [PATCH 2/3] refactor: just use _paths if present Signed-off-by: Henry Schreiner --- pyproject.toml | 1 - .../_compat/importlib/readers.py | 24 ------------------- src/scikit_build_core/builder/builder.py | 12 ++++++---- 3 files changed, 7 insertions(+), 30 deletions(-) delete mode 100644 src/scikit_build_core/_compat/importlib/readers.py diff --git a/pyproject.toml b/pyproject.toml index 8ee5c9c5..eb8d0ae1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -296,7 +296,6 @@ known-local-folder = ["pathutils"] "importlib_metadata".msg = "Use scikit_build_core._compat.importlib.metadata instead." "importlib.resources".msg = "Use scikit_build_core._compat.importlib.resources instead." "importlib_resources".msg = "Use scikit_build_core._compat.importlib.resources instead." -"importlib.readers".msg = "Use scikit_build_core._compat.importlib.readers instead." "pyproject_metadata".msg = "Use scikit_build_core._vendor.pyproject_metadata instead." diff --git a/src/scikit_build_core/_compat/importlib/readers.py b/src/scikit_build_core/_compat/importlib/readers.py deleted file mode 100644 index eb010349..00000000 --- a/src/scikit_build_core/_compat/importlib/readers.py +++ /dev/null @@ -1,24 +0,0 @@ -from __future__ import annotations - -import sys -from typing import TYPE_CHECKING - -if TYPE_CHECKING: - from pathlib import Path - -if sys.version_info < (3, 10): - # Readers and MultiplexedPath were introduced in 3.10, so nothing should output a MultiplexedPath - # It is also tricky because it is unclear if the `resource_loader` when calling `import` would create - # either importlib.readers.MultiplexedPath or importlib_resources.MultiplexedPath. - # Creating a dummy class instead so that if it fails, it fails completely (and mypy is made happy) - class MultiplexedPath: - _paths: list[Path] -else: - # From 3.11 this is an alias of importlib.resources.readers - from importlib.readers import MultiplexedPath - -__all__ = ["MultiplexedPath"] - - -def __dir__() -> list[str]: - return __all__ diff --git a/src/scikit_build_core/builder/builder.py b/src/scikit_build_core/builder/builder.py index f1ca53ac..9d2f7b09 100644 --- a/src/scikit_build_core/builder/builder.py +++ b/src/scikit_build_core/builder/builder.py @@ -10,7 +10,6 @@ from .. import __version__ from .._compat.importlib import metadata, resources -from .._compat.importlib.readers import MultiplexedPath from .._logging import logger from ..resources import find_python from .generator import set_environment_for_gen @@ -86,12 +85,15 @@ def _filter_env_cmake_args(env_cmake_args: list[str]) -> Generator[str, None, No yield arg -# Type-hinting for Traversable is rather hard because they were introduced in python 3.11. -# This avoids introducing importlib_resources dependency that may not be used in the actual package loader def _sanitize_path(path: os.PathLike[str]) -> list[Path]: - if isinstance(path, MultiplexedPath): + # This handles classes like: + # MultiplexedPath from importlib.resources.readers (3.11+) + # MultiplexedPath from importlib.readers (3.10) + # MultiplexedPath from importlib_resources.readers + if hasattr(path, "_paths"): # pylint: disable-next=protected-access - return path._paths + return path._paths # type: ignore[no-any-return] + return [Path(path)] From a5fdfa7f47b2a0ee5ad613f9b3cd40870cff92b5 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Tue, 10 Sep 2024 15:26:13 -0400 Subject: [PATCH 3/3] fix: make sure this goes through fspath Signed-off-by: Henry Schreiner --- src/scikit_build_core/builder/builder.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/scikit_build_core/builder/builder.py b/src/scikit_build_core/builder/builder.py index 9d2f7b09..437265f4 100644 --- a/src/scikit_build_core/builder/builder.py +++ b/src/scikit_build_core/builder/builder.py @@ -1,6 +1,7 @@ from __future__ import annotations import dataclasses +import os import re import shlex import sys @@ -22,7 +23,6 @@ ) if TYPE_CHECKING: - import os from collections.abc import Generator, Iterable, Mapping, Sequence from packaging.version import Version @@ -92,9 +92,9 @@ def _sanitize_path(path: os.PathLike[str]) -> list[Path]: # MultiplexedPath from importlib_resources.readers if hasattr(path, "_paths"): # pylint: disable-next=protected-access - return path._paths # type: ignore[no-any-return] + return [Path(os.fspath(p)) for p in path._paths] - return [Path(path)] + return [Path(os.fspath(path))] @dataclasses.dataclass