diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3b903d0..6ec55cd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -67,6 +67,11 @@ jobs: version: cp39-macosx_x86_64 - os: macOS-15 version: cp39-macosx_arm64 + # Free-threaded Python builds (3.14t) - no Limited API/Stable ABI + - os: macOS-15-intel + version: cp314t-macosx_x86_64 + - os: macOS-15 + version: cp314t-macosx_arm64 steps: - uses: actions/download-artifact@v6 @@ -113,6 +118,7 @@ jobs: - '3.12' - '3.13' - '3.14' + - '3.14t' provider: - mit - heimdal diff --git a/CHANGELOG.md b/CHANGELOG.md index a2a9117..9505680 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ * Build using the Stable ABI/Limited API with Python 3.11 and newer * Updated Cython build requirements to `3.2.1` +* Added support for Python free-threading (`PEP 779`) + * PyPI will contain wheels for macOS Python 3.14t + * Linux will still need to compile the extension at install time but will create a free-threaded wheel if running under that interpreter + * Python 3.13t is not supported or tested so may or may not work ## 0.8.0 - 2025-09-01 diff --git a/README.md b/README.md index 6abafc2..4a3485d 100644 --- a/README.md +++ b/README.md @@ -100,3 +100,11 @@ if not hasattr(krb5, "kt_dup"): There may also be some difference in behaviour, error codes, error messages, between te different implementations. It is up to the caller to paper over these differences when required. + +## Python Free-Threading (PEP 779) + +This library supports Python Free-Threading and will build free-threading-compatible extension files if installed under a free-threading interpreter. +Python 3.14t is tested in CI and a wheel for macOS will be created for 3.14t. +Python 3.13t is not officially tested or supported but may or may not work. +There is limited testing for free-threading in this library and it does not aim to be thread safe out of the box. +If you encounter any issues or problems with this scenario please raise an issue and we can look at possible options to fix this. diff --git a/setup.cfg b/setup.cfg index fcf7797..29bc222 100644 --- a/setup.cfg +++ b/setup.cfg @@ -21,6 +21,7 @@ classifiers = Programming Language :: Python :: 3.12 Programming Language :: Python :: 3.13 Programming Language :: Python :: 3.14 + Programming Language :: Python :: Free Threading :: 2 - Beta [options] package_dir = diff --git a/setup.py b/setup.py index 122eb73..0a68fea 100755 --- a/setup.py +++ b/setup.py @@ -19,6 +19,7 @@ import shlex import subprocess import sys +import sysconfig import typing from Cython.Build import cythonize @@ -32,6 +33,12 @@ USE_LIMITED_API = sys.version_info >= (3, 11) LIMITED_API_VERSION = 0x030B0000 # Python 3.11 ABI +IS_FREE_THREADED = False +if sysconfig.get_config_var("Py_GIL_DISABLED") == 1: + # Free-threaded Python does not support the limited API. + USE_LIMITED_API = False + IS_FREE_THREADED = True + def run_command(*args: str) -> str: stdout = subprocess.check_output(args, shell=True) @@ -278,11 +285,16 @@ def get_krb5_lib_path( # Hardcode this option in pyproject.toml once 3.11 is minimum. setup_options["bdist_wheel"] = {"py_limited_api": "cp311"} +compiler_directives = {"linetrace": CYTHON_LINETRACE} +if IS_FREE_THREADED: + # Enable free-threading support in Cython + compiler_directives["freethreading_compatible"] = True + setup( ext_modules=cythonize( raw_extensions, language_level=3, - compiler_directives={"linetrace": CYTHON_LINETRACE}, + compiler_directives=compiler_directives, ), options=setup_options, )