diff --git a/setup.py b/setup.py index 54d682065..6dc849763 100644 --- a/setup.py +++ b/setup.py @@ -4,6 +4,7 @@ import shutil import subprocess import sys +import sysconfig from pathlib import Path from setuptools import Extension, setup @@ -15,6 +16,24 @@ PROJ_VERSION_SEARCH = re.compile(r".*Rel\.\s+(?P\d+\.\d+\.\d+).*") VERSION_SEARCH = re.compile(r".*(?P\d+\.\d+\.\d+).*") +# restrict LIMITED_API usage: +# - require an env var PYPROJ_LIMITED_API=1 +# - LIMITED_API is not compatible with free-threading (as of CPython 3.14) +USE_PY_LIMITED_API = os.environ.get( + "PYPROJ_LIMITED_API" +) == "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 = [ + ("NPY_NO_DEPRECATED_API", "NPY_1_7_API_VERSION"), + # keep in sync with runtime requirements (pyproject.toml) + ("NPY_TARGET_VERSION", "NPY_1_23_API_VERSION"), +] +if USE_PY_LIMITED_API: + define_macros.append(("Py_LIMITED_API", ABI3_TARGET_HEX)) + def _parse_version(version: str) -> tuple[int, int, int]: """Convert a version string to a tuple of integers.""" @@ -198,6 +217,7 @@ def get_extension_modules(): library_dirs if os.name != "nt" and sys.platform != "cygwin" else None ), "libraries": get_libraries(library_dirs), + "py_limited_api": USE_PY_LIMITED_API, } # setup cythonized modules return cythonize( @@ -244,10 +264,16 @@ def get_package_data() -> dict[str, list[str]]: return package_data +if USE_PY_LIMITED_API: + options = {"bdist_wheel": {"py_limited_api": f"cp{ABI3_TARGET_VERSION}"}} +else: + options = {} + # static items in pyproject.toml setup( ext_modules=get_extension_modules(), package_data=get_package_data(), # temptorary hack to add in metadata url="https://github.com/pyproj4/pyproj", + options=options, )