Repository: scikit-build/scikit-build-core
Pull request #556 (2023-11-17 21:38:30)

feat: support namespaced config settings
Support namespaced config settings, `skbuild.X` now also works instead of just `X`.



Patch:
diff --git a/README.md b/README.md
index 585bb4e..c3843b3 100644
--- a/README.md
+++ b/README.md
@@ -328,7 +328,7 @@ use cases. This is the tool scikit-build-core itself uses.
 
 ## Acknowledgements
 
-Support for this work was provided by NSF cooperative agreement [OAC-2209877][].
+Support for this work was provided by NSF grant [OAC-2209877][].
 
 <!-- prettier-ignore-start -->
 [actions-badge]:            https://github.com/scikit-build/scikit-build-core/workflows/CI/badge.svg
diff --git a/src/scikit_build_core/settings/skbuild_read_settings.py b/src/scikit_build_core/settings/skbuild_read_settings.py
index 8e7af37..810e64b 100644
--- a/src/scikit_build_core/settings/skbuild_read_settings.py
+++ b/src/scikit_build_core/settings/skbuild_read_settings.py
@@ -179,9 +179,16 @@ class SettingsReader:
                     else:
                         tool_skb[key] = value
 
+        prefixed = {
+            k: v for k, v in config_settings.items() if k.startswith("skbuild.")
+        }
+        remaining = {
+            k: v for k, v in config_settings.items() if not k.startswith("skbuild.")
+        }
         self.sources = SourceChain(
             EnvSource("SKBUILD"),
-            ConfSource(settings=config_settings, verify=verify_conf),
+            ConfSource("skbuild", settings=prefixed, verify=verify_conf),
+            ConfSource(settings=remaining, verify=verify_conf),
             TOMLSource("tool", "scikit-build", settings=pyproject),
             prefixes=["tool", "scikit-build"],
         )
@@ -240,8 +247,10 @@ class SettingsReader:
         return result
 
     def print_suggestions(self) -> None:
-        for index in (1, 2):
-            name = {1: "config-settings", 2: "pyproject.toml"}[index]
+        for index in (1, 2, 3):
+            name = {1: "config-settings", 2: "config-settings", 3: "pyproject.toml"}[
+                index
+            ]
             suggestions_dict = self.suggestions(index)
             if suggestions_dict:
                 rich_print(f"[red][bold]ERROR:[/bold] Unrecognized options in {name}:")


Test patch:
diff --git a/tests/test_skbuild_settings.py b/tests/test_skbuild_settings.py
index 68c18e0..8aa9a7d 100644
--- a/tests/test_skbuild_settings.py
+++ b/tests/test_skbuild_settings.py
@@ -135,8 +135,9 @@ def test_skbuild_settings_envvar(tmp_path: Path, monkeypatch: pytest.MonkeyPatch
     assert not settings.install.strip
 
 
+@pytest.mark.parametrize("prefix", [True, False], ids=["skbuild", "noprefix"])
 def test_skbuild_settings_config_settings(
-    tmp_path: Path, monkeypatch: pytest.MonkeyPatch
+    tmp_path: Path, monkeypatch: pytest.MonkeyPatch, prefix: bool
 ):
     monkeypatch.setattr(
         scikit_build_core.settings.skbuild_read_settings, "__version__", "0.1.0"
@@ -177,6 +178,9 @@ def test_skbuild_settings_config_settings(
         "install.strip": "True",
     }
 
+    if prefix:
+        config_settings = {f"skbuild.{k}": v for k, v in config_settings.items()}
+
     settings_reader = SettingsReader.from_file(pyproject_toml, config_settings)
     settings = settings_reader.settings
     assert list(settings_reader.unrecognized_options()) == []