Skip to content

Commit 3d6cbc9

Browse files
authored
Merge pull request #770 from webknjaz/packaging/fix-build-hang-on-spawn-in-cythonize
📦 Disable `cythonize` parallelism w/ `spawn`
2 parents a220d06 + c4af16a commit 3d6cbc9

File tree

6 files changed

+128
-2
lines changed

6 files changed

+128
-2
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
770.packaging.rst
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
770.packaging.rst
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
A workaround has been applied to the in-tree build backend that prevents
2+
Cython from hanging when ``libssh`` header files are missing
3+
-- by :user:`webknjaz`.
4+
5+
The patch makes ``cythonize()`` single-threaded because :mod:`multiprocessing`
6+
gets stuck. The upstream will eventually fix this by migrating to
7+
:mod:`concurrent.futures`.

packaging/pep517_backend/_backend.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454

5555
from ._compat import chdir_cm, nullcontext_cm # noqa: WPS436
5656
from ._cython_configuration import ( # noqa: WPS436
57-
get_local_cython_config as _get_local_cython_config,
57+
get_local_cythonize_config as _get_local_cython_config,
5858
)
5959
from ._cython_configuration import ( # noqa: WPS436
6060
make_cythonize_cli_args_from_config as _make_cythonize_cli_args_from_config,

packaging/pep517_backend/_cython_configuration.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,63 @@ def get_local_cython_config() -> dict:
2121
:returns: config section from ``pyproject.toml``
2222
:rtype: dict
2323
24+
This basically reads entries from::
25+
26+
[tool.local.cython]
27+
# Env vars provisioned during cythonize call
28+
src = ["src/**/*.pyx"]
29+
30+
[tool.local.cython.env]
31+
# Env vars provisioned during cythonize call
32+
LDFLAGS = "-lssh"
33+
34+
[tool.local.cython.flags]
35+
# This section can contain the following booleans:
36+
# * annotate — generate annotated HTML page for source files
37+
# * build — build extension modules using distutils
38+
# * inplace — build extension modules in place using distutils (implies -b)
39+
# * force — force recompilation
40+
# * quiet — be less verbose during compilation
41+
# * lenient — increase Python compat by ignoring some compile time errors
42+
# * keep-going — compile as much as possible, ignore compilation failures
43+
annotate = false
44+
build = false
45+
inplace = true
46+
force = true
47+
quiet = false
48+
lenient = false
49+
keep-going = false
50+
51+
[tool.local.cython.kwargs]
52+
# This section can contain args that have values:
53+
# * exclude=PATTERN exclude certain file patterns from the compilation
54+
# * parallel=N run builds in N parallel jobs (default: calculated per system)
55+
exclude = "**.py"
56+
parallel = 12
57+
58+
[tool.local.cython.kwargs.directives]
59+
# This section can contain compiler directives
60+
# NAME = "VALUE"
61+
62+
[tool.local.cython.kwargs.compile-time-env]
63+
# This section can contain compile time env vars
64+
# NAME = "VALUE"
65+
66+
[tool.local.cython.kwargs.options]
67+
# This section can contain cythonize options
68+
# NAME = "VALUE"
69+
"""
70+
config_toml_txt = (Path.cwd().resolve() / 'pyproject.toml').read_text()
71+
config_mapping = load_toml_from_string(config_toml_txt)
72+
return config_mapping['tool']['local']['cython']
73+
74+
75+
def get_local_cythonize_config() -> dict:
76+
"""Grab optional build dependencies from pyproject.toml config.
77+
78+
:returns: config section from ``pyproject.toml``
79+
:rtype: dict
80+
2481
This basically reads entries from::
2582
2683
[tool.local.cythonize]

pyproject.toml

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,60 @@ requires = [
1515
backend-path = ["packaging"] # requires 'Pip>=20' or 'pep517>=0.6.0'
1616
build-backend = "pep517_backend.hooks"
1717

18+
[tool.local.cython]
19+
# This attr can contain multiple globs
20+
src = ["src/**/*.pyx"]
21+
22+
[tool.local.cython.env]
23+
# Env vars provisioned during cythonize call
24+
#ANSIBLE_PYLIBSSH_CYTHON_TRACING = "1"
25+
#CFLAGS = "-DCYTHON_TRACE=1 ${CFLAGS}"
26+
LDFLAGS = "-lssh ${LDFLAGS}"
27+
28+
[tool.local.cython.flags]
29+
# This section can contain the following booleans:
30+
# * annotate — generate annotated HTML page for source files
31+
# * build — build extension modules using distutils
32+
# * inplace — build extension modules in place using distutils (implies -b)
33+
# * force — force recompilation
34+
# * quiet — be less verbose during compilation
35+
# * lenient — increase Python compat by ignoring some compile time errors
36+
# * keep-going — compile as much as possible, ignore compilation failures
37+
annotate = false
38+
build = false
39+
inplace = true
40+
force = true
41+
quiet = false
42+
lenient = false
43+
keep-going = false
44+
45+
[tool.local.cython.kwargs]
46+
# This section can contain args tha have values:
47+
# * exclude=PATTERN exclude certain file patterns from the compilation
48+
# * parallel=N run builds in N parallel jobs (default: calculated per system)
49+
# exclude = "**.py"
50+
# parallel = 12
51+
52+
[tool.local.cython.kwargs.directive]
53+
# This section can contain compiler directives
54+
# Ref: https://github.com/cython/cython/blob/d6e6de9/Cython/Compiler/Options.py#L170-L242
55+
embedsignature = "True"
56+
emit_code_comments = "True"
57+
linetrace = "True"
58+
profile = "True"
59+
60+
[tool.local.cython.kwargs.compile-time-env]
61+
# This section can contain compile time env vars
62+
63+
[tool.local.cython.kwargs.option]
64+
# This section can contain cythonize options
65+
# Ref: https://github.com/cython/cython/blob/d6e6de9/Cython/Compiler/Options.py#L694-L730
66+
#docstrings = "True"
67+
#embed_pos_in_docstring = "True"
68+
#warning_errors = "True"
69+
#error_on_unknown_names = "True"
70+
#error_on_uninitialized = "True"
71+
1872
[tool.local.cythonize]
1973
# This attr can contain multiple globs
2074
src = ["src/**/*.pyx"]
@@ -47,7 +101,13 @@ keep-going = false
47101
# * exclude=PATTERN exclude certain file patterns from the compilation
48102
# * parallel=N run builds in N parallel jobs (default: calculated per system)
49103
# exclude = "**.py"
50-
# parallel = 12
104+
#
105+
# NOTE: Setting parallelism to 1 works around a bug in the ``cythonize``
106+
# NOTE: script that hangs on macOS under Python 3.8+ due to the use of
107+
# NOTE: the ``spawn`` method in ``multiprocessing``. This patch can be
108+
# NOTE: reverted once the fix PR is usable upstream.
109+
# Ref: https://github.com/cython/cython/pull/7183
110+
parallel = 1
51111

52112
[tool.local.cythonize.kwargs.directive]
53113
# This section can contain compiler directives

0 commit comments

Comments
 (0)