One convenient way to do this automatically is to use the sys._is_gil_enabled() method to check if the macro needs to be used. A recipe like this might work:
macros = []
if getattr(sys, “_is_gil_enabled”, None) and not sys._is_gil_enabled():
macros = [(“Py_GIL_DISABLED”,”1″)]
ext_modules = [
Extension(
“compute”,
[“compute.pyx”],
define_macros=macros
)
]
4. Ensure your code is thread safe
Thread safety in Cython modules has always been the programmer’s responsibility, at least as far as pure C code goes. If you call into the CPython interpreter using Cython, even in the free-threaded build, the interpreter will handle reference counts for those objects (although it won’t do anything about data races). But any Cython functions that run concurrently must not manipulate the same data.
New type annotations for constants, pointers, and volatile values
As Cython has evolved, it has gradually transitioned away from its custom Python-but-not-quite syntax. Modern Cython uses a syntax that is essentially regular Python with Cython-added type hints, context managers, and other constructions.