Skip to content

Commit

Permalink
[legacy] root: Fix compilation with Python 3.11
Browse files Browse the repository at this point in the history
  • Loading branch information
dennisklein committed Nov 25, 2022
1 parent fb31f62 commit 7dd9ab8
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 0 deletions.
3 changes: 3 additions & 0 deletions cmake/legacy.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,9 @@ ExternalProject_Add(root
GIT_REPOSITORY https://github.com/root-project/root/ GIT_TAG v${root_version_gittag}
GIT_SHALLOW 1
PATCH_COMMAND ${patch} -p1 -i "${CMAKE_SOURCE_DIR}/legacy/root/fix_compilation_with_gcc12.patch"
COMMAND ${patch} -p1 -i "${CMAKE_SOURCE_DIR}/legacy/root/fix_pyroot_code_h_inclusion_python_3_11.patch"
COMMAND ${patch} -p1 -i "${CMAKE_SOURCE_DIR}/legacy/root/fix_tpython_python_3_11_deprecation.patch"
COMMAND ${patch} -p1 -i "${CMAKE_SOURCE_DIR}/legacy/root/fix_pyroot_cast_error_python_3_11.patch"
${CMAKE_DEFAULT_ARGS} CMAKE_ARGS
"-Daqua=ON"
"-Dasimage=ON"
Expand Down
24 changes: 24 additions & 0 deletions legacy/root/fix_pyroot_cast_error_python_3_11.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
commit 98ad99126cd7f2754dc02ae7e82288d435fec341
Author: Enric Tejedor Saavedra <enric.tejedor.saavedra@cern.ch>
Date: Fri Jun 10 16:42:49 2022 +0200

[PyROOT] Prevent cast error when calling PyTuple_SET_ITEM in 3.11

PyTuple_SET_ITEM ends up calling _PyObject_CAST(nullptr) which
causes "error: invalid cast from type 'std::nullptr_t' to type
'const PyObject*' {aka 'const _object*'}

diff --git a/bindings/pyroot/cppyy/CPyCppyy/src/CPPMethod.cxx b/bindings/pyroot/cppyy/CPyCppyy/src/CPPMethod.cxx
index 685ad3dc60..2189348594 100644
--- a/bindings/pyroot/cppyy/CPyCppyy/src/CPPMethod.cxx
+++ b/bindings/pyroot/cppyy/CPyCppyy/src/CPPMethod.cxx
@@ -580,7 +580,7 @@ PyObject* CPyCppyy::CPPMethod::ProcessKeywords(PyObject* self, PyObject* args, P
// set all values to zero to be able to check them later (this also guarantees normal
// cleanup by the tuple deallocation)
for (Py_ssize_t i = 0; i < nArgs+nKeys; ++i)
- PyTuple_SET_ITEM(newArgs, i, nullptr);
+ PyTuple_SET_ITEM(newArgs, i, static_cast<PyObject*>(nullptr));

// next, insert the keyword values
PyObject *key, *value;

29 changes: 29 additions & 0 deletions legacy/root/fix_pyroot_code_h_inclusion_python_3_11.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
commit c861479d05885c2b8250ac03da96bacfe034d30a
Author: Enric Tejedor Saavedra <enric.tejedor.saavedra@cern.ch>
Date: Thu Jun 9 12:24:07 2022 +0200

[PyROOT] code.h must not be included directly in 3.11

It has been moved to Include/cpython, and it is included by Python.h.

See:
https://docs.python.org/3.11/whatsnew/3.11.html

diff --git a/bindings/pyroot/cppyy/CPyCppyy/src/CPPOverload.cxx b/bindings/pyroot/cppyy/CPyCppyy/src/CPPOverload.cxx
index 146ca01389..97e557a1b2 100644
--- a/bindings/pyroot/cppyy/CPyCppyy/src/CPPOverload.cxx
+++ b/bindings/pyroot/cppyy/CPyCppyy/src/CPPOverload.cxx
@@ -1,10 +1,10 @@
// Bindings
#include "CPyCppyy.h"
#include "structmember.h" // from Python
-#if PY_VERSION_HEX >= 0x02050000
-#include "code.h" // from Python
-#else
+#if PY_VERSION_HEX < 0x02050000
#include "compile.h" // from Python
+#elif PY_VERSION_HEX < 0x030b0000
+#include "code.h" // from Python
#endif
#ifndef CO_NOFREE
// python2.2 does not have CO_NOFREE defined
71 changes: 71 additions & 0 deletions legacy/root/fix_tpython_python_3_11_deprecation.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
commit dc4e620480c77f8fc9b51075f28fa57413464fde
Author: Enric Tejedor Saavedra <enric.tejedor.saavedra@cern.ch>
Date: Fri Jun 10 16:07:10 2022 +0200

[TPython] PySys_SetArgv is deprecated in 3.11

We should use the new PyConfig API of the Python Initialization
Configuration instead.

See:
https://docs.python.org/3.11/whatsnew/3.11.html#id7

diff --git a/bindings/tpython/src/TPython.cxx b/bindings/tpython/src/TPython.cxx
index 5cae95abbb..a98d1134e5 100644
--- a/bindings/tpython/src/TPython.cxx
+++ b/bindings/tpython/src/TPython.cxx
@@ -120,7 +120,37 @@ Bool_t TPython::Initialize()
#if PY_VERSION_HEX < 0x03020000
PyEval_InitThreads();
#endif
+
+// set the command line arguments on python's sys.argv
+#if PY_VERSION_HEX < 0x03000000
+ char *argv[] = {const_cast<char *>("root")};
+#else
+ wchar_t *argv[] = {const_cast<wchar_t *>(L"root")};
+#endif
+ int argc = sizeof(argv) / sizeof(argv[0]);
+#if PY_VERSION_HEX < 0x030b0000
Py_Initialize();
+#else
+ PyStatus status;
+ PyConfig config;
+
+ PyConfig_InitPythonConfig(&config);
+
+ status = PyConfig_SetArgv(&config, argc, argv);
+ if (PyStatus_Exception(status)) {
+ PyConfig_Clear(&config);
+ std::cerr << "Error when setting command line arguments." << std::endl;
+ return kFALSE;
+ }
+
+ status = Py_InitializeFromConfig(&config);
+ if (PyStatus_Exception(status)) {
+ PyConfig_Clear(&config);
+ std::cerr << "Error when initializing Python." << std::endl;
+ return kFALSE;
+ }
+ PyConfig_Clear(&config);
+#endif
#if PY_VERSION_HEX >= 0x03020000
#if PY_VERSION_HEX < 0x03090000
PyEval_InitThreads();
@@ -134,13 +164,9 @@ Bool_t TPython::Initialize()
return kFALSE;
}

-// set the command line arguments on python's sys.argv
-#if PY_VERSION_HEX < 0x03000000
- char *argv[] = {const_cast<char *>("root")};
-#else
- wchar_t *argv[] = {const_cast<wchar_t *>(L"root")};
+#if PY_VERSION_HEX < 0x030b0000
+ PySys_SetArgv(argc, argv);
#endif
- PySys_SetArgv(sizeof(argv) / sizeof(argv[0]), argv);

// force loading of the ROOT module
const int ret = PyRun_SimpleString(const_cast<char *>("import ROOT"));

0 comments on commit 7dd9ab8

Please sign in to comment.