diff --git a/.github/workflows/root-ci.yml b/.github/workflows/root-ci.yml index cf125674dae16..62f1d11953631 100644 --- a/.github/workflows/root-ci.yml +++ b/.github/workflows/root-ci.yml @@ -415,10 +415,11 @@ jobs: is_special: true property: "clang Ninja builtins auto-registration off" overrides: ["CMAKE_CXX_STANDARD=20"] - # Fedora Rawhide with Python debug build + # Fedora Rawhide with Python freethreading+debug build - image: rawhide + python_venv: "/py-venv-3.14td/ROOT-CI" is_special: true - property: "Fedora pydebug" + property: "Fedora pydebug no GIL" overrides: ["CMAKE_CXX_STANDARD=23"] # Minimal build - image: alma10 @@ -466,14 +467,15 @@ jobs: BUILD_DIR: /github/home/ROOT-CI/build INSTALL_DIR: /github/home/ROOT-CI/install POST_INSTALL_DIR: /github/home/ROOT-CI/PostInstall + PYTHON_VENV: ${{ matrix.python_venv || '/py-venv/ROOT-CI' }} steps: - name: Set up environment run: | ccache -o max_size=${{ matrix.is_special && '5G' || '1.5G' }} ccache -s || true - if [ -d /py-venv/ROOT-CI/bin/ ]; then - . /py-venv/ROOT-CI/bin/activate && echo PATH=$PATH >> $GITHUB_ENV; + if [ -d "$PYTHON_VENV/bin/" ]; then + . "$PYTHON_VENV/bin/activate" && echo PATH=$PATH >> $GITHUB_ENV; fi if ${{ contains(matrix.property, 'auto-registration off') }}; then echo "Disabling ROOT's object auto registration for this job" diff --git a/bindings/pyroot/pythonizations/CMakeLists.txt b/bindings/pyroot/pythonizations/CMakeLists.txt index 2cd037d234b6c..32d7d54b8dad4 100644 --- a/bindings/pyroot/pythonizations/CMakeLists.txt +++ b/bindings/pyroot/pythonizations/CMakeLists.txt @@ -37,7 +37,8 @@ if (Python3_VERSION VERSION_GREATER_EQUAL "3.11") # On Windows we can't use the stable ABI yet: it requires linking against a # different libpython, so as long as we don't build all translation units in # the ROOT Pythonization library with the stable ABI we should not use it. - if(NOT MSVC) + # Free-threaded (Py_GIL_DISABLED) interpreters don't support the limited API. + if(NOT MSVC AND NOT Python3_GIL_DISABLED) target_compile_options(${libname} PRIVATE -DPy_LIMITED_API=0x030B0000) endif() endif() diff --git a/bindings/tpython/CMakeLists.txt b/bindings/tpython/CMakeLists.txt index c48b3250ffba8..b724647ab0dbc 100644 --- a/bindings/tpython/CMakeLists.txt +++ b/bindings/tpython/CMakeLists.txt @@ -36,7 +36,8 @@ if (Python3_VERSION VERSION_GREATER_EQUAL "3.10") # On Windows we can't use the stable ABI yet: it requires linking against a # different libpython, so as long as we don't build all translation units in # the ROOT Pythonization library with the stable ABI we should not use it. - if(NOT MSVC) + # Free-threaded (Py_GIL_DISABLED) interpreters don't support the limited API. + if(NOT MSVC AND NOT Python3_GIL_DISABLED) target_compile_options(ROOTTPython PRIVATE -DPy_LIMITED_API=0x030A0000) endif() endif() diff --git a/cmake/modules/SearchInstalledSoftware.cmake b/cmake/modules/SearchInstalledSoftware.cmake index d5727658c9550..09225aa7dbd0b 100644 --- a/cmake/modules/SearchInstalledSoftware.cmake +++ b/cmake/modules/SearchInstalledSoftware.cmake @@ -418,6 +418,33 @@ if(tmva-pymva OR tmva-sofie) endif() find_package(Python3 3.10 COMPONENTS ${python_components}) +# Detect whether the found Python interpreter is a free-threaded build +# (Py_GIL_DISABLED is defined in pyconfig.h). The limited C API is not +# supported in free-threaded builds; including Python.h with Py_LIMITED_API +# defined produces a hard error there +# (https://docs.python.org/3/howto/free-threading-extensions.html). +# Checking the preprocessor symbol directly is more reliable than asking the +# interpreter (e.g. sysconfig.get_config_var may misreport, and +# sys._is_gil_enabled() can be overridden at runtime via PYTHON_GIL=1). +set(Python3_GIL_DISABLED FALSE) +if(Python3_Development_FOUND OR Python3_Development.Module_FOUND) + include(CheckCXXSourceCompiles) + set(_old_required_includes ${CMAKE_REQUIRED_INCLUDES}) + set(CMAKE_REQUIRED_INCLUDES ${Python3_INCLUDE_DIRS}) + check_cxx_source_compiles(" + #include + #ifndef Py_GIL_DISABLED + #error \"GIL is not disabled\" + #endif + int main() { return 0; } + " ROOT_PYTHON_GIL_DISABLED) + set(CMAKE_REQUIRED_INCLUDES ${_old_required_includes}) + if(ROOT_PYTHON_GIL_DISABLED) + set(Python3_GIL_DISABLED TRUE) + message(STATUS "Python ${Python3_VERSION} is a free-threaded build (Py_GIL_DISABLED defined); the limited C API will not be used") + endif() +endif() + #---Check for OpenGL installation------------------------------------------------------- # OpenGL is required by various graf3d features that are enabled with opengl=ON, # or by the Cocoa-related code that always requires it. diff --git a/roottest/scripts/custom_diff.py b/roottest/scripts/custom_diff.py index 112c10228ffb6..c16788fb79389 100755 --- a/roottest/scripts/custom_diff.py +++ b/roottest/scripts/custom_diff.py @@ -33,6 +33,7 @@ def __init__(self): r"^In file included from input_line", # Wrapper input line r"^[:space:]*$", # Lines which are empty apart from spaces r"^Info in : Object auto registration", # ROOT 7 mode + r"^:\d+: RuntimeWarning: The global interpreter lock \(GIL\) has been enabled", # Free-threaded Python re-enabling the GIL to load a C extension that isn't GIL-safe ] ]