From 01a79df26dbb00cca02fe0574a391f3aae3627a9 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Fri, 20 Sep 2024 14:55:13 -0400 Subject: [PATCH] fix: avoid providing prepare-metadata methods if rebuild is True (#904) Reported in https://github.com/rapidfuzz/RapidFuzz/pull/397. This avoids declaring the optional hooks if there's a good chance it can't be computed reliably. Having an override with `failed` can't be computed without trying to build. --------- Signed-off-by: Henry Schreiner --- docs/overrides.md | 4 ++ src/scikit_build_core/build/__init__.py | 60 +++++++++++++++++-------- 2 files changed, 46 insertions(+), 18 deletions(-) diff --git a/docs/overrides.md b/docs/overrides.md index e367d7a1..a313ffac 100644 --- a/docs/overrides.md +++ b/docs/overrides.md @@ -212,6 +212,10 @@ wheel.cmake = false ::: +If this override is present in your pyproject.toml file, scikit-build-core will not +provide the `prepare_metadata_*` hooks, as it can't know without building if the build +will fail. + ## Any matching condition If you use `if.any` instead of `if`, then the override is true if any one of the diff --git a/src/scikit_build_core/build/__init__.py b/src/scikit_build_core/build/__init__.py index 93cbc252..89f5698c 100644 --- a/src/scikit_build_core/build/__init__.py +++ b/src/scikit_build_core/build/__init__.py @@ -6,6 +6,8 @@ import sys +from .._compat import tomllib + __all__ = [ "build_editable", "build_sdist", @@ -66,29 +68,51 @@ def build_editable( raise SystemExit(1) from None -def prepare_metadata_for_build_wheel( - metadata_directory: str, - config_settings: dict[str, list[str] | str] | None = None, -) -> str: - """Prepare metadata for building a wheel. Does not build the wheel. Returns the dist-info directory.""" - from .wheel import _build_wheel_impl +def _has_safe_metadata() -> bool: + try: + with open("pyproject.toml", "rb") as f: # noqa: PTH123 + pyproject = tomllib.load(f) + except FileNotFoundError: + return True - return _build_wheel_impl( - None, config_settings, metadata_directory, editable=False - ).wheel_filename # actually returns the dist-info directory + overrides = pyproject.get("tool", {}).get("scikit-build", {}).get("overrides", []) + for override in overrides: + if_override = override.get("if", {}) + if "failed" in if_override or "failed" in if_override.get("any", {}): + return False + return True -def prepare_metadata_for_build_editable( - metadata_directory: str, - config_settings: dict[str, list[str] | str] | None = None, -) -> str: - """Prepare metadata for building a wheel. Does not build the wheel. Returns the dist-info directory.""" - from .wheel import _build_wheel_impl +if _has_safe_metadata(): - return _build_wheel_impl( - None, config_settings, metadata_directory, editable=True - ).wheel_filename # actually returns the dist-info directory + def prepare_metadata_for_build_wheel( + metadata_directory: str, + config_settings: dict[str, list[str] | str] | None = None, + ) -> str: + """Prepare metadata for building a wheel. Does not build the wheel. Returns the dist-info directory.""" + from .wheel import _build_wheel_impl + + return _build_wheel_impl( + None, config_settings, metadata_directory, editable=False + ).wheel_filename # actually returns the dist-info directory + + def prepare_metadata_for_build_editable( + metadata_directory: str, + config_settings: dict[str, list[str] | str] | None = None, + ) -> str: + """Prepare metadata for building a wheel. Does not build the wheel. Returns the dist-info directory.""" + + from .wheel import _build_wheel_impl + + return _build_wheel_impl( + None, config_settings, metadata_directory, editable=True + ).wheel_filename # actually returns the dist-info directory + + __all__ += [ + "prepare_metadata_for_build_wheel", + "prepare_metadata_for_build_editable", + ] def build_sdist(