|
1 | 1 | from __future__ import annotations |
2 | 2 |
|
3 | 3 | import dataclasses |
| 4 | +import enum |
4 | 5 | import os |
5 | 6 | import re |
6 | 7 | import shlex |
|
35 | 36 | DIR = Path(__file__).parent.resolve() |
36 | 37 |
|
37 | 38 |
|
| 39 | +class _SabiMode(enum.Enum): |
| 40 | + NONE = enum.auto() |
| 41 | + ABI3 = enum.auto() |
| 42 | + ABI3T = enum.auto() |
| 43 | + |
| 44 | + |
38 | 45 | def __dir__() -> list[str]: |
39 | 46 | return __all__ |
40 | 47 |
|
@@ -211,61 +218,46 @@ def configure( |
211 | 218 |
|
212 | 219 | py_api = self.settings.wheel.py_api |
213 | 220 | gil_disabled = bool(sysconfig.get_config_var("Py_GIL_DISABLED")) |
214 | | - ft_abi = limited_api is True and gil_disabled |
215 | | - if limited_api is None: |
216 | | - if py_api.startswith("cp3"): |
217 | | - if py_api.endswith("t"): |
218 | | - # Free-threaded stable ABI (PEP 803 / abi3t) |
219 | | - target_minor_version = int(py_api[3:-1]) |
220 | | - if ( |
221 | | - sys.implementation.name == "cpython" |
222 | | - and gil_disabled |
223 | | - and target_minor_version <= sys.version_info.minor |
224 | | - ): |
225 | | - ft_abi = True |
226 | | - limited_api = True |
227 | | - else: |
228 | | - limited_api = False |
229 | | - logger.info( |
230 | | - "py-api {} requires free-threaded CPython >= 3.{}, ignoring", |
231 | | - py_api, |
232 | | - target_minor_version, |
233 | | - ) |
| 221 | + |
| 222 | + sabi = _SabiMode.NONE |
| 223 | + if limited_api is True: |
| 224 | + # Handle externally-set limited_api (e.g. from setuptools) |
| 225 | + if sys.implementation.name != "cpython": |
| 226 | + logger.info("PyPy doesn't support the Limited API, ignoring") |
| 227 | + elif gil_disabled: |
| 228 | + sabi = _SabiMode.ABI3T |
| 229 | + else: |
| 230 | + sabi = _SabiMode.ABI3 |
| 231 | + elif limited_api is None and py_api.startswith("cp3"): |
| 232 | + target_minor_version = int(py_api[3:].rstrip("t")) |
| 233 | + if sys.implementation.name != "cpython": |
| 234 | + logger.info("py-api {} requires CPython, ignoring") |
| 235 | + elif py_api.endswith("t"): |
| 236 | + # Free-threaded stable ABI (PEP 803 / abi3t) |
| 237 | + if gil_disabled and target_minor_version <= sys.version_info.minor: |
| 238 | + sabi = _SabiMode.ABI3T |
234 | 239 | else: |
235 | | - # Classic stable ABI (abi3) |
236 | | - target_minor_version = int(py_api[3:]) |
237 | | - if sys.implementation.name != "cpython": |
238 | | - limited_api = False |
239 | | - logger.info("PyPy doesn't support the Limited API, ignoring") |
240 | | - elif gil_disabled: |
241 | | - limited_api = False |
242 | | - logger.info( |
243 | | - "Free-threaded Python doesn't support the classic Limited API, ignoring" |
244 | | - ) |
245 | | - else: |
246 | | - limited_api = target_minor_version <= sys.version_info.minor |
| 240 | + logger.info( |
| 241 | + "py-api {} requires free-threaded CPython >= 3.{}, ignoring", |
| 242 | + py_api, |
| 243 | + target_minor_version, |
| 244 | + ) |
247 | 245 | else: |
248 | | - limited_api = False |
249 | | - |
250 | | - # Handle externally-set limited_api (e.g. from setuptools) |
251 | | - if (limited_api or ft_abi) and sys.implementation.name != "cpython": |
252 | | - limited_api = False |
253 | | - ft_abi = False |
254 | | - logger.info("PyPy doesn't support the Limited API, ignoring") |
255 | | - |
256 | | - if limited_api and gil_disabled and not ft_abi: |
257 | | - limited_api = False |
258 | | - logger.info( |
259 | | - "Free-threaded Python doesn't support the classic Limited API, ignoring" |
260 | | - ) |
| 246 | + # Classic stable ABI (abi3) |
| 247 | + target_minor_version = int(py_api[3:]) |
| 248 | + if gil_disabled: |
| 249 | + logger.info( |
| 250 | + "Free-threaded Python doesn't support the classic Limited API, ignoring" |
| 251 | + ) |
| 252 | + elif target_minor_version <= sys.version_info.minor: |
| 253 | + sabi = _SabiMode.ABI3 |
261 | 254 |
|
262 | 255 | python_library = get_python_library(self.config.env, abi3=False) |
263 | 256 | python_sabi_library = None |
264 | | - if limited_api: |
265 | | - if ft_abi: |
266 | | - python_sabi_library = get_python_library(self.config.env, abi3t=True) |
267 | | - else: |
268 | | - python_sabi_library = get_python_library(self.config.env, abi3=True) |
| 257 | + if sabi == _SabiMode.ABI3T: |
| 258 | + python_sabi_library = get_python_library(self.config.env, abi3t=True) |
| 259 | + elif sabi == _SabiMode.ABI3: |
| 260 | + python_sabi_library = get_python_library(self.config.env, abi3=True) |
269 | 261 | python_include_dir = get_python_include_dir() |
270 | 262 | numpy_include_dir = get_numpy_include_dir() |
271 | 263 |
|
@@ -302,24 +294,26 @@ def configure( |
302 | 294 | cache_config[f"{prefix}_NumPy_INCLUDE_DIR"] = numpy_include_dir |
303 | 295 |
|
304 | 296 | cache_config["SKBUILD_SOABI"] = get_soabi( |
305 | | - self.config.env, abi3=(limited_api and not ft_abi), abi3t=ft_abi |
| 297 | + self.config.env, |
| 298 | + abi3=(sabi == _SabiMode.ABI3), |
| 299 | + abi3t=(sabi == _SabiMode.ABI3T), |
306 | 300 | ) |
307 | 301 |
|
308 | 302 | # Allow CMakeLists to detect this is supposed to be a limited ABI build |
309 | 303 | cache_config["SKBUILD_SABI_COMPONENT"] = ( |
310 | | - "Development.SABIModule" if limited_api else "" |
| 304 | + "Development.SABIModule" if sabi != _SabiMode.NONE else "" |
311 | 305 | ) |
312 | 306 |
|
313 | 307 | # Allow users to detect the version requested in settings |
314 | | - if limited_api and py_api.startswith("cp"): |
| 308 | + if sabi != _SabiMode.NONE and py_api.startswith("cp"): |
315 | 309 | version_str = py_api[2:] |
316 | 310 | if version_str.endswith("t"): |
317 | 311 | version_str = version_str[:-1] |
318 | 312 | cache_config["SKBUILD_SABI_VERSION"] = f"{version_str[0]}.{version_str[1:]}" |
319 | 313 | else: |
320 | 314 | cache_config["SKBUILD_SABI_VERSION"] = "" |
321 | 315 |
|
322 | | - if ft_abi: |
| 316 | + if sabi == _SabiMode.ABI3T: |
323 | 317 | cache_config["Py_TARGET_ABI3T"] = "1" |
324 | 318 |
|
325 | 319 | if cache_entries: |
|
0 commit comments