From 89627a77258ea9e333dceac535cab050cfa80adf Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Fri, 1 Nov 2024 15:47:29 +0000 Subject: [PATCH 1/2] Set `Py_GIL_DISABLED=1` for free threading on Windows When free threaded CPython is installed from the official Windows installer it doesn't have the macro `Py_GIL_DISABLED` properly set becuase its `pyconfig.h` file is shared across the co-installed default build. Define the macro when building free threaded Python extensions on Windows so that each individual C API extension doesn't have to work around this limitation. See https://github.com/pypa/setuptools/issues/4662 --- distutils/command/build_ext.py | 8 +++++++- distutils/util.py | 4 ++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/distutils/command/build_ext.py b/distutils/command/build_ext.py index a7e3038b..8d3dd768 100644 --- a/distutils/command/build_ext.py +++ b/distutils/command/build_ext.py @@ -23,7 +23,7 @@ ) from ..extension import Extension from ..sysconfig import customize_compiler, get_config_h_filename, get_python_version -from ..util import get_platform, is_mingw +from ..util import get_platform, is_mingw, is_freethreaded # An extension name is just a dot-separated list of Python NAMEs (ie. # the same as a fully-qualified module name). @@ -333,6 +333,12 @@ def run(self): # noqa: C901 if os.name == 'nt' and self.plat_name != get_platform(): self.compiler.initialize(self.plat_name) + # The official Windows free threaded Python installer doesn't set + # Py_GIL_DISABLED because its pyconfig.h is shared with the + # default build, so we need to define it here. + if os.name == 'nt' and is_freethreaded(): + self.compiler.define_macro('Py_GIL_DISABLED', '1') + # And make sure that any compile/link-related options (which might # come from the command-line or from the setup script) are set in # that CCompiler object -- that way, they automatically apply to diff --git a/distutils/util.py b/distutils/util.py index 609c1a50..6ef2c985 100644 --- a/distutils/util.py +++ b/distutils/util.py @@ -503,3 +503,7 @@ def is_mingw(): get_platform() starts with 'mingw'. """ return sys.platform == 'win32' and get_platform().startswith('mingw') + +def is_freethreaded(): + """Return True if the Python interpreter is built with free threading support.""" + return bool(sysconfig.get_config_var('Py_GIL_DISABLED')) From de1e6245eece2b51df15d42a49bf5a406cc71f78 Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Fri, 1 Nov 2024 16:18:27 +0000 Subject: [PATCH 2/2] Link to setuptools issue --- distutils/command/build_ext.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/distutils/command/build_ext.py b/distutils/command/build_ext.py index 8d3dd768..271378e5 100644 --- a/distutils/command/build_ext.py +++ b/distutils/command/build_ext.py @@ -335,7 +335,8 @@ def run(self): # noqa: C901 # The official Windows free threaded Python installer doesn't set # Py_GIL_DISABLED because its pyconfig.h is shared with the - # default build, so we need to define it here. + # default build, so we need to define it here + # (see pypa/setuptools#4662). if os.name == 'nt' and is_freethreaded(): self.compiler.define_macro('Py_GIL_DISABLED', '1')