|
24 | 24 | import os
|
25 | 25 | from collections.abc import Generator, Mapping
|
26 | 26 |
|
| 27 | + from .skbuild_overrides import OverrideRecord |
| 28 | + |
27 | 29 |
|
28 | 30 | __all__ = ["SettingsReader"]
|
29 | 31 |
|
@@ -133,6 +135,57 @@ def _handle_move(
|
133 | 135 | return before
|
134 | 136 |
|
135 | 137 |
|
| 138 | +def _validate_overrides( |
| 139 | + settings: ScikitBuildSettings, |
| 140 | + overrides: dict[str, OverrideRecord], |
| 141 | +) -> None: |
| 142 | + """Validate all fields with any override information.""" |
| 143 | + |
| 144 | + def validate_field( |
| 145 | + field: dataclasses.Field[Any], |
| 146 | + value: Any, |
| 147 | + prefix: str = "", |
| 148 | + record: OverrideRecord | None = None, |
| 149 | + ) -> None: |
| 150 | + """Do the actual validation.""" |
| 151 | + # Check if we had a hard-coded value in the record |
| 152 | + conf_key = field.name.replace("_", "-") |
| 153 | + if field.metadata.get("disallow_hard_code", False): |
| 154 | + original_value = record.original_value if record else value |
| 155 | + if original_value is not None: |
| 156 | + msg = f"{prefix}{conf_key} is not allowed to be hard-coded in the pyproject.toml file" |
| 157 | + if settings.strict_config: |
| 158 | + sys.stdout.flush() |
| 159 | + rich_print(f"{{bold.red}}ERROR:{{normal}} {msg}") |
| 160 | + raise SystemExit(7) |
| 161 | + logger.warning(msg) |
| 162 | + |
| 163 | + def validate_field_recursive( |
| 164 | + obj: Any, |
| 165 | + record: OverrideRecord | None = None, |
| 166 | + prefix: str = "", |
| 167 | + ) -> None: |
| 168 | + """Navigate through all the keys and validate each field.""" |
| 169 | + for field in dataclasses.fields(obj): |
| 170 | + conf_key = field.name.replace("_", "-") |
| 171 | + closest_record = overrides.get(f"{prefix}{conf_key}", record) |
| 172 | + value = getattr(obj, field.name) |
| 173 | + # Do the validation of the current field |
| 174 | + validate_field( |
| 175 | + field=field, |
| 176 | + value=value, |
| 177 | + prefix=prefix, |
| 178 | + record=closest_record, |
| 179 | + ) |
| 180 | + if dataclasses.is_dataclass(value): |
| 181 | + validate_field_recursive( |
| 182 | + obj=value, record=closest_record, prefix=f"{prefix}{conf_key}." |
| 183 | + ) |
| 184 | + |
| 185 | + # Navigate all fields starting from the top-level |
| 186 | + validate_field_recursive(obj=settings) |
| 187 | + |
| 188 | + |
136 | 189 | class SettingsReader:
|
137 | 190 | def __init__(
|
138 | 191 | self,
|
@@ -352,6 +405,7 @@ def validate_may_exit(self) -> None:
|
352 | 405 | self.print_suggestions()
|
353 | 406 | raise SystemExit(7)
|
354 | 407 | logger.warning("Unrecognized options: {}", ", ".join(unrecognized))
|
| 408 | + _validate_overrides(self.settings, self.overriden_items) |
355 | 409 |
|
356 | 410 | for key, value in self.settings.metadata.items():
|
357 | 411 | if "provider" not in value:
|
|
0 commit comments