From 2f787b9cabd090d00be3b7cb261aac551eff13ce Mon Sep 17 00:00:00 2001 From: Lysandros Nikolaou Date: Mon, 15 Jul 2024 14:03:04 +0200 Subject: [PATCH 1/4] Document Cython's freethreading_compatible directive --- docs/porting.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/porting.md b/docs/porting.md index 1d1dfdd..edf22e9 100644 --- a/docs/porting.md +++ b/docs/porting.md @@ -22,17 +22,18 @@ Extension modules need to explicitly indicate they support running with the GIL disabled, otherwise a warning is printed and the GIL is re-enabled at runtime after importing a module that does not support the GIL. -!!! note - - Currently it is not possible for extensions written in Cython to declare - they support running without the GIL. Work is under way to add support - (see [cython#6242](https://github.com/cython/cython/pull/6242)). - C++ extension modules making use of `pybind11` can easily declare support for running with the GIL disabled via the [`gil_not_used`](https://pybind11.readthedocs.io/en/stable/reference.html#_CPPv4N7module_23create_extension_moduleEPKcPKcP10module_def16mod_gil_not_used) argument to `create_extension_module`. +Starting with Cython 3.1.0 (only available via the nightly wheels), extension +modules written in Cython can also do so using the +[`freethreading_compatible`](https://cython.readthedocs.io/en/latest/src/userguide/source_files_and_compilation.html#compiler-directives) +compiler directive. It can be enabled either per module or globally by adding +`-Xfreethreading_comparible=True` to the Cython arguments via the project's +build system. + C or C++ extension modules using multi-phase initialization can specify the [`Py_mod_gil`](https://docs.python.org/3.13/c-api/module.html#c.Py_mod_gil) module slot like this: From cd2ba2347432409a906a072aae520dff1580366e Mon Sep 17 00:00:00 2001 From: Lysandros Nikolaou Date: Mon, 15 Jul 2024 15:28:03 +0200 Subject: [PATCH 2/4] Address feedback Co-authored-by: Ralf Gommers --- docs/porting.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/porting.md b/docs/porting.md index edf22e9..3d4a438 100644 --- a/docs/porting.md +++ b/docs/porting.md @@ -27,11 +27,12 @@ running with the GIL disabled via the [`gil_not_used`](https://pybind11.readthedocs.io/en/stable/reference.html#_CPPv4N7module_23create_extension_moduleEPKcPKcP10module_def16mod_gil_not_used) argument to `create_extension_module`. -Starting with Cython 3.1.0 (only available via the nightly wheels), extension -modules written in Cython can also do so using the +Starting with Cython 3.1.0 (only available via the nightly wheels or the `master` +branch as of right now), extension modules written in Cython can also do so using the [`freethreading_compatible`](https://cython.readthedocs.io/en/latest/src/userguide/source_files_and_compilation.html#compiler-directives) -compiler directive. It can be enabled either per module or globally by adding -`-Xfreethreading_comparible=True` to the Cython arguments via the project's +compiler directive. It can be enabled either per module as a directive +(`# cython: freethreading_compatible=True`) in `.pyx` files, or globally by adding +`-Xfreethreading_compatible=True` to the Cython arguments via the project's build system. C or C++ extension modules using multi-phase initialization can specify the From a94ec7db5011e4445a7d3b313571264b6fc973ec Mon Sep 17 00:00:00 2001 From: Lysandros Nikolaou Date: Tue, 16 Jul 2024 12:41:49 +0200 Subject: [PATCH 3/4] Add build examples --- docs/porting.md | 53 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/docs/porting.md b/docs/porting.md index 3d4a438..133989d 100644 --- a/docs/porting.md +++ b/docs/porting.md @@ -35,6 +35,59 @@ compiler directive. It can be enabled either per module as a directive `-Xfreethreading_compatible=True` to the Cython arguments via the project's build system. +Here are a few examples of how to globally enable the directive in a few popular +build systems: + +=== "setuptools" + + When using setuptools, you can pass the `compiler_directives` keyword argument + to `cythonize`: + + ```python + from Cython.Compiler.Version import version as cython_version + from packaging.version import Version + + compiler_directives = {...} + if Version(cython_version) >= Version("3.1.0a1"): + compiler_directives["freethreading_compatible"] = True + + setup( + ext_modules=cythonize( + extensions, + compiler_directives=compiler_directives, + ) + ) + ``` + +=== "Meson" + + When using Meson, you can add the directive to the `cython_args` you're + passing to `py.extension_module`: + + ```meson + cy = meson.get_compiler('cython') + + cython_args = [...] + if cy.version().version_compare('>=3.1.0') + cython_args += ['-Xfreethreading_compatible=True'] + endif + + py.extension_module('modulename' + 'source.pyx', + cython_args: cython_args, + ... + ) + ``` + + You can also globally add the directive for all Cython extension modules: + + ```meson + cy = meson.get_compiler('cython') + if cy.version().version_compare('>=3.1.0') + add_global_arguments('-Xfreethreading_compatible=true', language : 'cython') + endif + ``` + C or C++ extension modules using multi-phase initialization can specify the [`Py_mod_gil`](https://docs.python.org/3.13/c-api/module.html#c.Py_mod_gil) module slot like this: From 51c813c8eaff37654464903fee8b90246f905648 Mon Sep 17 00:00:00 2001 From: Lysandros Nikolaou Date: Tue, 16 Jul 2024 13:49:56 +0200 Subject: [PATCH 4/4] Address feedback; don't use Ellipsis & use add_project_arguments Co-authored-by: Ralf Gommers --- docs/porting.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/porting.md b/docs/porting.md index 133989d..cdb4b79 100644 --- a/docs/porting.md +++ b/docs/porting.md @@ -47,7 +47,7 @@ build systems: from Cython.Compiler.Version import version as cython_version from packaging.version import Version - compiler_directives = {...} + compiler_directives = {} if Version(cython_version) >= Version("3.1.0a1"): compiler_directives["freethreading_compatible"] = True @@ -67,7 +67,7 @@ build systems: ```meson cy = meson.get_compiler('cython') - cython_args = [...] + cython_args = [] if cy.version().version_compare('>=3.1.0') cython_args += ['-Xfreethreading_compatible=True'] endif @@ -84,7 +84,7 @@ build systems: ```meson cy = meson.get_compiler('cython') if cy.version().version_compare('>=3.1.0') - add_global_arguments('-Xfreethreading_compatible=true', language : 'cython') + add_project_arguments('-Xfreethreading_compatible=true', language : 'cython') endif ```