Skip to content

Commit 545a83a

Browse files
authored
feat: if for free-threading (#819)
~~I think this won't work on Windows yet, we'll need to find the flags another way there, I think.~~ Now uses packaging.tags. Close #770. --------- Signed-off-by: Henry Schreiner <[email protected]>
1 parent 4923ded commit 545a83a

File tree

7 files changed

+65
-4
lines changed

7 files changed

+65
-4
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ features over classic Scikit-build:
6363
soon)
6464
- Experimental editable mode support, with optional experimental auto rebuilds
6565
on import and optional in-place mode
66-
- Supports WebAssembly (Emscripten/Pyodide).
67-
- Supports free-threaded Python 3.13.
66+
- Supports WebAssembly (Emscripten/[Pyodide](https://pyodide.org)).
67+
- Supports [free-threaded Python 3.13](https://py-free-threading.github.io).
6868

6969
The following limitations are present compared to classic scikit-build:
7070

@@ -117,7 +117,7 @@ the minimum to get started.
117117
An example `CMakeLists.txt`:
118118

119119
```cmake
120-
cmake_minimum_required(VERSION 3.15...3.27)
120+
cmake_minimum_required(VERSION 3.15...3.30)
121121
project(${SKBUILD_PROJECT_NAME} LANGUAGES C)
122122
123123
find_package(Python COMPONENTS Interpreter Development.Module REQUIRED)

docs/overrides.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ Example:
2929

3030
```toml
3131
[[tool.scikit-build.overrides]]
32-
if.python_version = ">=3.13"
32+
if.python-version = ">=3.13"
3333
wheel.cmake = false
3434
```
3535

@@ -84,6 +84,10 @@ A few sample values:
8484
| Windows | ARM | `ARM64` |
8585

8686

87+
### `abi-flags` (string)
88+
89+
A sorted list of the ABI flags. `t` is the free-threaded build.
90+
8791
### `platform-node` (string)
8892

8993
The value of `platform.node()`. This is generally your computer's name. Takes a

src/scikit_build_core/builder/sysconfig.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,15 @@
77
from pathlib import Path
88
from typing import TYPE_CHECKING
99

10+
import packaging.tags
11+
1012
from .._logging import logger, rich_print
1113

1214
if TYPE_CHECKING:
1315
from collections.abc import Mapping
1416

1517
__all__ = [
18+
"get_abi_flags",
1619
"get_cmake_platform",
1720
"get_numpy_include_dir",
1821
"get_python_include_dir",
@@ -184,6 +187,19 @@ def get_numpy_include_dir() -> Path | None:
184187
return Path(np.get_include())
185188

186189

190+
def get_abi_flags() -> str:
191+
"""
192+
Return the ABI flags for the current Python interpreter. Derived from
193+
``packaging.tags.sys_tags()`` since that works on Windows.
194+
"""
195+
196+
most_compatible = next(iter(packaging.tags.sys_tags()))
197+
full_abi = most_compatible.abi
198+
vers = packaging.tags.interpreter_version()
199+
abi_flags = full_abi[full_abi.find(vers) + len(vers) :]
200+
return "".join(sorted(abi_flags))
201+
202+
187203
def info_print(*, color: str = "") -> None:
188204
"""
189205
Print information about the Python environment.
@@ -208,6 +224,7 @@ def info_print(*, color: str = "") -> None:
208224
rich_print(
209225
f"[bold {color}]Detected ABI3 SOABI:[/bold] {get_soabi(os.environ, abi3=True)}"
210226
)
227+
rich_print(f"[bold {color}Detected ABI flags:[/bold] {get_abi_flags()}")
211228

212229

213230
if __name__ == "__main__":

src/scikit_build_core/resources/scikit-build.schema.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,10 @@
667667
"type": "boolean",
668668
"description": "Whether a cmake wheel is known to be provided for this system."
669669
},
670+
"abi-flags": {
671+
"type": "string",
672+
"description": "A sorted string of the abi flags. Takes a regex."
673+
},
670674
"env": {
671675
"type": "object",
672676
"patternProperties": {

src/scikit_build_core/settings/skbuild_overrides.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
from .._compat import tomllib
1414
from .._logging import logger
15+
from ..builder.sysconfig import get_abi_flags
1516
from ..cmake import CMake
1617
from ..errors import CMakeNotFoundError
1718
from ..resources import resources
@@ -76,6 +77,7 @@ def override_match(
7677
failed: bool | None = None,
7778
system_cmake: str | None = None,
7879
cmake_wheel: bool | None = None,
80+
abi_flags: str | None = None,
7981
) -> tuple[dict[str, str], set[str]]:
8082
"""
8183
Check if the current environment matches the overrides. Returns a dict
@@ -191,6 +193,14 @@ def override_match(
191193
else:
192194
failed_set.add("cmake-wheel")
193195

196+
if abi_flags is not None:
197+
current_abi_flags = get_abi_flags()
198+
match_msg = regex_match(current_abi_flags, abi_flags)
199+
if match_msg:
200+
passed_dict["abi-flags"] = match_msg
201+
else:
202+
failed_set.add("abi-flags")
203+
194204
if env:
195205
for key, value in env.items():
196206
if key not in current_env:

src/scikit_build_core/settings/skbuild_schema.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,10 @@ def generate_skbuild_schema(tool_name: str = "scikit-build") -> dict[str, Any]:
132132
"type": "boolean",
133133
"description": "Whether a cmake wheel is known to be provided for this system.",
134134
},
135+
"abi-flags": {
136+
"type": "string",
137+
"description": "A sorted string of the abi flags. Takes a regex.",
138+
},
135139
"env": {
136140
"type": "object",
137141
"patternProperties": {

tests/test_settings_overrides.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22

3+
import sysconfig
34
import typing
45
from pathlib import Path
56
from textwrap import dedent
@@ -540,6 +541,7 @@ def test_skbuild_overrides_from_sdist(
540541
tmp_path / ("from_sdist" if from_sdist else "not_from_sdist") / "pyproject.toml"
541542
)
542543
pyproject_toml.parent.mkdir(exist_ok=True)
544+
543545
pyproject_toml.write_text(
544546
dedent(
545547
"""\
@@ -666,3 +668,23 @@ def test_system_cmake(
666668
settings_reader = SettingsReader.from_file(pyproject_toml, retry=False)
667669
settings = settings_reader.settings
668670
assert settings.wheel.cmake == (cmake_version == "3.27")
671+
672+
673+
def test_free_threaded_override(tmp_path: Path):
674+
pyproject_toml = tmp_path / "pyproject.toml"
675+
pyproject_toml.write_text(
676+
dedent(
677+
"""\
678+
[tool.scikit-build]
679+
wheel.cmake = false
680+
681+
[[tool.scikit-build.overrides]]
682+
if.abi-flags = "t"
683+
wheel.cmake = true
684+
"""
685+
)
686+
)
687+
688+
settings_reader = SettingsReader.from_file(pyproject_toml, state="wheel")
689+
settings = settings_reader.settings
690+
assert settings.wheel.cmake == bool(sysconfig.get_config_var("Py_GIL_DISABLED"))

0 commit comments

Comments
 (0)