8000 Merge pull request #26950 from ngoldbaum/cython-free-threading · numpy/numpy@9b9a5da · GitHub
[go: up one dir, main page]

Skip to content

Commit 9b9a5da

Browse files
authored
Merge pull request #26950 from ngoldbaum/cython-free-threading
MAINT: add freethreading_compatible directive to cython build
2 parents 66e1e36 + 072bd3c commit 9b9a5da

File tree

7 files changed

+54
-7
lines changed

7 files changed

+54
-7
lines changed

.github/workflows/linux.yml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,17 @@ jobs:
309309
# TODO: remove cython nightly install when cython does a release
310310
- name: Install nightly Cython
311311
run: |
312-
pip install git+https://github.com/cython/cython
312+
pip install -i https://pypi.anaconda.org/scientific-python-nightly-wheels/simple cython
313+
# Set PYTHON_GIL=0 to force GIL off during tests and then manually verify
314+
# importing numpy does not enable the GIL. When f2py grows the ability to
315+
# declare GIL-disabled support we can just run the tests without the
316+
# environment variable
313317
- uses: ./.github/meson_actions
314318
env:
315319
PYTHON_GIL: 0
320+
- name: Verify import does not re-enable GIL
321+
run: |
322+
if [[ $(python -c "import numpy" 2>&1) == "*The global interpreter lock (GIL) has been enabled*" ]]; then
323+
echo "Error: Importing NumPy re-enables the GIL in the free-threaded build"
324+
exit 1
325+
fi

numpy/_core/tests/examples/cython/meson.build

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ if not cy.version().version_compare('>=3.0.6')
1010
error('tests requires Cython >= 3.0.6')
1111
endif
1212

13+
cython_args = []
14+
if cy.version().version_compare('>=3.1.0')
15+
cython_args += ['-Xfreethreading_compatible=True']
16+
endif
17+
1318
npy_include_path = run_command(py, [
1419
'-c',
1520
'import os; os.chdir(".."); import numpy; print(os.path.abspath(numpy.get_include()))'
@@ -34,4 +39,5 @@ py.extension_module(
3439
'-DNPY_TARGET_VERSION=NPY_2_0_API_VERSION',
3540
],
3641
include_directories: [npy_include_path],
42+
cython_args: cython_args,
3743
)

numpy/_core/tests/examples/cython/setup.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
for testing.
44
"""
55

6+
import Cython
67
import numpy as np
8+
from numpy._utils import _pep440
79
from distutils.core import setup
810
from Cython.Build import cythonize
911
from setuptools.extension import Extension
@@ -24,6 +26,12 @@
2426

2527
extensions = [checks]
2628

29+
compiler_directives = {}
30+
if _pep440.parse(Cython.__version__) >= _pep440.parse("3.1.0a0"):
31+
compiler_directives['freethreading_compatible'] = True
32+
2733
setup(
28-
ext_modules=cythonize(extensions)
34+
ext_modules=cythonize(
35+
extensions,
36+
compiler_directives=compiler_directives)
2937
)

numpy/meson.build

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ install_subdir('tests', install_dir: np_dir, install_tag: 'tests')
369369
compilers = {
370370
'C': cc,
371371
'CPP': cpp,
372-
'CYTHON': meson.get_compiler('cython')
372+
'CYTHON': cy,
373373
}
374374

375375
machines = {

numpy/random/_examples/cython/meson.build

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ if not cy.version().version_compare('>=3.0.6')
1111
error('tests requires Cython >= 3.0.6')
1212
endif
1313

14+
base_cython_args = []
15+
if cy.version().version_compare('>=3.1.0a0')
16+
base_cython_args += ['-Xfreethreading_compatible=True']
17+
endif
18+
1419
_numpy_abs = run_command(py3, ['-c',
1520
'import os; os.chdir(".."); import numpy; print(os.path.abspath(numpy.get_include() + "../../.."))'],
1621
check: true).stdout().strip()
@@ -27,20 +32,22 @@ py3.extension_module(
2732
install: false,
2833
include_directories: [npy_include_path],
2934
dependencies: [npyrandom_lib, npymath_lib],
35+
cython_args: base_cython_args,
3036
)
3137
py3.extension_module(
3238
'extending',
3339
'extending.pyx',
3440
install: false,
3541
include_directories: [npy_include_path],
3642
dependencies: [npyrandom_lib, npymath_lib],
43+
cython_args: base_cython_args,
3744
)
3845
py3.extension_module(
3946
'extending_cpp',
4047
'extending_distributions.pyx',
4148
install: false,
4249
override_options : ['cython_language=cpp'],
43-
cython_args: ['--module-name', 'extending_cpp'],
50+
cython_args: base_cython_args + ['--module-name', 'extending_cpp'],
4451
include_directories: [npy_include_path],
4552
dependencies: [npyrandom_lib, npymath_lib],
4653
)

numpy/random/meson.build

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ if host_machine.system() == 'cygwin'
5252
c_args_random += ['-Wl,--export-all-symbols']
5353
endif
5454

55+
cython_args = []
56+
if cy.version().version_compare('>=3.1.0')
57+
cython_args += ['-Xfreethreading_compatible=True']
58+
endif
59+
5560
# name, sources, extra c_args, extra static libs to link
5661
random_pyx_sources = [
5762
['_bounded_integers', _bounded_integers_pyx, [], [npyrandom_lib, npymath_lib]],
@@ -83,6 +88,7 @@ foreach gen: random_pyx_sources
8388
link_with: gen[3],
8489
install: true,
8590
subdir: 'numpy/random',
91+
cython_args: cython_args,
8692
)
8793
endforeach
8894

tools/wheels/cibw_test_command.sh

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,19 @@ if [[ $FREE_THREADED_BUILD == "True" ]]; then
3434
# with a released version of cython
3535
python -m pip uninstall -y cython
3636
python -m pip install -i https://pypi.anaconda.org/scientific-python-nightly-wheels/simple cython
37-
# TODO: delete when importing numpy no longer enables the GIL
38-
# setting to zero ensures the GIL is disabled while running the
39-
# tests under free-threaded python
37+
38+
# Manually check that importing NumPy does not re-enable the GIL.
39+
# Afterwards, force the GIL to always be disabled so it does not get
40+
# re-enabled during the tests.
41+
#
42+
# TODO: delete when f2py grows the ability to define extensions that declare
43+
# they can run without the gil or when we can work around the fact the f2py
44+
# tests import modules that don't declare gil-disabled support.
45+
if [[ $(python -c "import numpy" 2>&1) == "*The global interpreter lock (GIL) has been enabled*" ]]; then
46+
echo "Error: Importing NumPy re-enables the GIL in the free-threaded build"
47+
exit 1
48+
fi
49+
4050
export PYTHON_GIL=0
4151
fi
4252

0 commit comments

Comments
 (0)
0