Skip to content

Commit c12572b

Browse files
authored
Document Cython's freethreading_compatible directive (#35)
1 parent a94fff8 commit c12572b

File tree

1 file changed

+61
-6
lines changed

1 file changed

+61
-6
lines changed

docs/porting.md

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,72 @@ Extension modules need to explicitly indicate they support running with the GIL
2222
disabled, otherwise a warning is printed and the GIL is re-enabled at runtime
2323
after importing a module that does not support the GIL.
2424

25-
!!! note
26-
27-
Currently it is not possible for extensions written in Cython to declare
28-
they support running without the GIL. Work is under way to add support
29-
(see [cython#6242](https://github.com/cython/cython/pull/6242)).
30-
3125
C++ extension modules making use of `pybind11` can easily declare support for
3226
running with the GIL disabled via the
3327
[`gil_not_used`](https://pybind11.readthedocs.io/en/stable/reference.html#_CPPv4N7module_23create_extension_moduleEPKcPKcP10module_def16mod_gil_not_used)
3428
argument to `create_extension_module`.
3529

30+
Starting with Cython 3.1.0 (only available via the nightly wheels or the `master`
31+
branch as of right now), extension modules written in Cython can also do so using the
32+
[`freethreading_compatible`](https://cython.readthedocs.io/en/latest/src/userguide/source_files_and_compilation.html#compiler-directives)
33+
compiler directive. It can be enabled either per module as a directive
34+
(`# cython: freethreading_compatible=True`) in `.pyx` files, or globally by adding
35+
`-Xfreethreading_compatible=True` to the Cython arguments via the project's
36+
build system.
37+
38+
Here are a few examples of how to globally enable the directive in a few popular
39+
build systems:
40+
41+
=== "setuptools"
42+
43+
When using setuptools, you can pass the `compiler_directives` keyword argument
44+
to `cythonize`:
45+
46+
```python
47+
from Cython.Compiler.Version import version as cython_version
48+
from packaging.version import Version
49+
50+
compiler_directives = {}
51+
if Version(cython_version) >= Version("3.1.0a1"):
52+
compiler_directives["freethreading_compatible"] = True
53+
54+
setup(
55+
ext_modules=cythonize(
56+
extensions,
57+
compiler_directives=compiler_directives,
58+
)
59+
)
60+
```
61+
62+
=== "Meson"
63+
64+
When using Meson, you can add the directive to the `cython_args` you're
65+
passing to `py.extension_module`:
66+
67+
```meson
68+
cy = meson.get_compiler('cython')
69+
70+
cython_args = []
71+
if cy.version().version_compare('>=3.1.0')
72+
cython_args += ['-Xfreethreading_compatible=True']
73+
endif
74+
75+
py.extension_module('modulename'
76+
'source.pyx',
77+
cython_args: cython_args,
78+
...
79+
)
80+
```
81+
82+
You can also globally add the directive for all Cython extension modules:
83+
84+
```meson
85+
cy = meson.get_compiler('cython')
86+
if cy.version().version_compare('>=3.1.0')
87+
add_project_arguments('-Xfreethreading_compatible=true', language : 'cython')
88+
endif
89+
```
90+
3691
C or C++ extension modules using multi-phase initialization can specify the
3792
[`Py_mod_gil`](https://docs.python.org/3.13/c-api/module.html#c.Py_mod_gil)
3893
module slot like this:

0 commit comments

Comments
 (0)