diff --git a/pyproject.toml b/pyproject.toml index d3379cfbc..b5589768c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -108,6 +108,7 @@ test-sources = ["pyproject.toml"] test-command = [ "pytest --pyargs bottleneck", ] +environment = { "BN_LIMITED_API" = "1" } [tool.ruff] exclude = [ diff --git a/setup.py b/setup.py index a5c07b7c2..124276cbf 100644 --- a/setup.py +++ b/setup.py @@ -3,6 +3,7 @@ import os import shutil import sys +import sysconfig from distutils.command.config import config as _config from setuptools import Command, setup @@ -11,10 +12,22 @@ import versioneer +# restrict LIMITED_API usage: +# - require BN_LIMITED_API=1 +# - LIMITED_API is not compatible with free-threading (as of CPython 3.14) +USE_PY_LIMITED_API = os.getenv( + "BN_LIMITED_API", "0" +) == "1" and not sysconfig.get_config_var("Py_GIL_DISABLED") +ABI3_TARGET_VERSION = "".join(str(_) for _ in sys.version_info[:2]) +ABI3_TARGET_HEX = hex(sys.hexversion & 0xFFFF00F0) + + define_macros = [ # keep in sync with runtime requirements (pyproject.toml) ("NPY_NO_DEPRECATED_API", "NPY_1_23_API_VERSION"), ] +if USE_PY_LIMITED_API: + define_macros.append(("Py_LIMITED_API", ABI3_TARGET_HEX)) class config(_config): @@ -151,6 +164,11 @@ def prepare_modules(): return ext +if USE_PY_LIMITED_API: + options = {"bdist_wheel": {"py_limited_api": f"cp{ABI3_TARGET_VERSION}"}} +else: + options = {} + setup( version=versioneer.get_version(), package_data={ @@ -158,4 +176,5 @@ def prepare_modules(): }, cmdclass=cmdclass, ext_modules=prepare_modules(), + options=options, )