Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
99 commits
Select commit Hold shift + click to select a range
bed51b7
[cling] Never resolve JIT symbols against legacy MSVC runtimes
guitargeek Jul 17, 2026
d4fd298
[cppinterop] Add Cling-specific RAII, lookup and dispatch patches [up…
aaronj0 Apr 23, 2026
f410207
[cppinterop] Fix JitCall codegen for deleted copy ctor in args [upstr…
aaronj0 May 11, 2026
0eeeee3
[cppinterop] Use canonical return type in wrapper codegen [upstream]
aaronj0 May 21, 2026
c4b89e2
[cppinterop] Null-guard GetClassTemplateInstantiationArgs [upstream]
aaronj0 Jul 11, 2026
016a55b
[cppinterop] Use `::new` in wrappers that placement-new into a caller…
guitargeek Jul 14, 2026
cc3b006
[cppinterop] Keep template arguments qualified in GetCompleteName [up…
guitargeek Jul 14, 2026
00059f8
[cppinterop] Cycle through ambiguous lookups in ExistsFunctionTemplat…
guitargeek Jul 14, 2026
23ec35c
[cppinterop] Compile call wrappers without access control [upstream]
guitargeek Jul 14, 2026
a720294
[cppinterop] Do not expose inherited special-member constructors [ups…
guitargeek Jul 14, 2026
53d8262
[cppinterop] Use the defining declaration's type for unbounded arrays…
guitargeek Jul 14, 2026
bfa576b
[cppinterop] Reject ill-formed instantiations in BestOverloadFunction…
guitargeek Jul 14, 2026
95850c3
[cppinterop] Make IsAbstract safe for classes without a definition [u…
guitargeek Jul 14, 2026
489637d
[cppinterop] Open a transaction before lookups that may deserialize […
guitargeek Jul 15, 2026
3e638d5
[cppinterop] Search base classes in GetNamed for class scopes [upstream]
guitargeek Jul 15, 2026
c71e43b
[cppinterop] Print type and scope names platform-independently [upstr…
guitargeek Jul 16, 2026
bc5107d
[cppinterop] Guard GetSizeOfType against a null type [upstream]
guitargeek Jul 16, 2026
7f7ce83
[cppinterop] Skip linkage specs when walking up parent scopes [upstream]
guitargeek Jul 17, 2026
867f7ae
[cppinterop] Use IsCopyConstructorDeleted for by-value args in calls …
guitargeek Jul 17, 2026
d039e2c
[cppinterop] Resolve globals whose symbol exists in no loaded binary …
guitargeek Jul 14, 2026
4ccb37c
[cppinterop] Return enum constant values as their int64_t bit pattern…
aaronj0 May 11, 2026
38d284d
[cppinterop] Keep only public using-shadows in class enumeration [ups…
guitargeek Jul 19, 2026
7585182
[cppinterop] Require public path between same-template base instantia…
guitargeek Jul 19, 2026
354ed4e
[cppyy-backend] Replace clingwrapper with compres forks [fork-baseline]
aaronj0 Apr 23, 2026
5451247
[cppyy-backend] Make GetActualClass robust across platforms [upstream]
aaronj0 May 11, 2026
2e1d5e0
[cppyy-backend] Pass CPPINTEROP_DIR directly to AddIncludePath [ROOT-…
aaronj0 May 19, 2026
8c05ca0
[cppyy-backend] Apply ROOT patches on compres fork baseline [ROOT-patch]
aaronj0 Apr 23, 2026
2e0e548
[cppyy-backend] Stage CppInterOp headers via etc/cppinterop [ROOT-patch]
aaronj0 May 19, 2026
05f2e16
[cppyy-backend] Resolve template arguments with real C++ unqualified …
aaronj0 Jul 11, 2026
739c46a
[cppyy-backend] Serialize CppInterOp calls with ROOT's interpreter lo…
guitargeek Jul 14, 2026
a53fcdf
[cppyy-backend] Resolve qualified names relative to a parent scope [u…
guitargeek Jul 14, 2026
9449d09
[cppyy-backend] Filter deleted functions from Python-visible overload…
guitargeek Jul 14, 2026
0e5737d
[cppyy-backend] Resolve cppyy.gbl.gROOT to its underlying variable [R…
guitargeek Jul 14, 2026
0205819
[cppyy-backend] Fix compiler warnings [upstream]
guitargeek Jul 15, 2026
5246efc
[cppyy-backend] Add env-guarded tracing of JIT calls [ROOT-patch]
guitargeek Jul 16, 2026
2c3bc7d
[cppyy-backend] Do not call with an unsizable return buffer in CallO …
guitargeek Jul 16, 2026
f45caf0
[cppyy-backend] Instantiate templated operator-> in smart-ptr detecti…
guitargeek Jul 17, 2026
3c8c0e3
[cppyy-backend] Return GetEnumDataValue as long long for int64 enum v…
aaronj0 May 11, 2026
c75a08e
[cppyy-backend] Don't autocast to anonymous-namespace types in GetAct…
guitargeek Jul 21, 2026
4e870c0
[CPyCppyy] Replace with compres forks [fork-baseline]
aaronj0 Apr 23, 2026
553c253
[CPyCppyy] Refactor the global call-policy system into GlobalPolicyFl…
aaronj0 Apr 24, 2026
f4e897e
[CPyCppyy] Add converters/low-level views for fixed width integers [u…
aaronj0 Apr 24, 2026
659e37d
[CPyCppyy] Fix typos, call GetActualClass in instance cast_actual [up…
aaronj0 Apr 23, 2026
7879893
[CPyCppyy] Add CStringArrayConverter::ToMemory and buffer helper [ups…
aaronj0 Apr 24, 2026
a6c1405
[CPyCppyy] Pythonize: fix __iadd__ return and disable buggy __array__…
aaronj0 Apr 24, 2026
35ec6a1
[CPyCppyy] Use complete basic_string<char> name with default template…
aaronj0 Apr 30, 2026
2fc10bb
[CPyCppyy] Match function-pointer overloads via TCppType_t [upstream]
aaronj0 May 4, 2026
2a6750c
[CPyCppyy] declare gException, drop CPYCPPYY_IMPORT from CPPInstance …
aaronj0 Apr 24, 2026
34af926
[CPyCppyy] Add more converter/executor name aliases [ROOT-patch]
aaronj0 Apr 24, 2026
1569eb4
[CPyCppyy] Rename PyInit_libcppyy to Init for ROOT module split [ROOT…
aaronj0 Apr 24, 2026
f750b3a
[CPyCppyy] Pythonize: add std::span support and no-std wstring aliase…
aaronj0 Apr 24, 2026
13de595
[CPyCppyy] Add __template_args__ and signature-plus-template overload…
aaronj0 Apr 23, 2026
cf329a3
[CPyCppyy] Always convert returned to Python string [ROOT-patch]
aaronj0 May 1, 2026
f3ba886
[CPyCppyy] Fix false addition of STLSequenceIter for pointer return-t…
aaronj0 May 3, 2026
8575e3d
[CPyCppyy] Restore support for non-const void*& arguments [upstream]
guitargeek Jul 14, 2026
7d93629
[CPyCppyy] Cache anonymous-enum constant values in CPPDataMember [ups…
guitargeek Jul 14, 2026
9c03cf6
[CPyCppyy] Exempt T* const& from the mutable pointer-reference ban [u…
guitargeek Jul 14, 2026
2d0f2e5
[CPyCppyy] Raise TypeError when a C++ name cannot be constructed [ups…
guitargeek Jul 14, 2026
377f5f1
[CPyCppyy] Re-enable __array__ for vectors of non-class element types…
guitargeek Jul 14, 2026
243a2f3
[CPyCppyy] Only pythonize size() as __len__ for integer-sized contain…
guitargeek Jul 14, 2026
70c6bdb
[CPyCppyy] Auto-downcast polymorphic pointers read from memory [upstr…
guitargeek Jul 14, 2026
8f9fbd7
[CPyCppyy] Do not declare the Cppyy API dllimport on Windows [ROOT-pa…
guitargeek Jul 15, 2026
d0c4563
[CPyCppyy] Retry template lookup with 2-tuples typed as std::pair [up…
guitargeek Jul 15, 2026
de7ee32
[CPyCppyy] Type Python complex as std::complex<double> in template ar…
guitargeek Jul 15, 2026
e53fc5f
[CPyCppyy] Do not implicitly convert to unrelated stdlib implementati…
guitargeek Jul 17, 2026
fa953f4
[CPyCppyy] Return GetEnumDataValue as long long for int64 enum values…
aaronj0 May 11, 2026
98cb87a
[CPyCppyy] Expose non-public methods re-exposed via public using-decl…
guitargeek Jul 19, 2026
ea09c3a
[CPyCppyy] Use comparison operators inherited from base classes [upst…
guitargeek Jul 19, 2026
bb4bbb4
[CPyCppyy] Search the global scope before the left operand's namespac…
guitargeek Jul 19, 2026
f1ab880
[CPyCppyy] Honor the global policy flag for implicit smart pointer co…
guitargeek Jul 19, 2026
e1b54c1
[CPyCppyy] Import cppyy module when gThisModule is null [ROOT-patch]
guitargeek Jul 31, 2026
2d4388d
[CPyCppyy] Reuse InitializerListConverter element converters [ROOT-pa…
guitargeek Aug 26, 2025
e04a4c2
[CPyCppyy] Exclude std::tuple from aggregate pseudo-constructor [ROOT…
aaronj0 Sep 29, 2024
e05e5c9
[CPyCppyy] Clear stale Python errors for debug-Python builds [ROOT-pa…
Vipul-Cariappa Jul 1, 2025
cd773c6
[CPyCppyy] Detect enum args by type in overload priority [ROOT-patch]
aaronj0 Aug 2, 2026
c861730
[CPyCppyy] Do not decref a constructor result on Windows [ROOT-patch]
guitargeek Aug 7, 2026
3d71912
[cppyy] Replace frontend with compres forks [fork-baseline]
aaronj0 Apr 24, 2026
57ffe3d
[cppyy] Match basic_string names with and without default template ar…
aaronj0 Apr 30, 2026
0ada8a2
[cppyy] Apply ROOT-specific patches [ROOT-patch]
aaronj0 Apr 24, 2026
4e1b889
[cppyy] Remove old patches and patching script for cppyy [ROOT-patch]
guitargeek Jul 14, 2026
dfa15c0
[cppyy] Enable test21_access_to_global_variables now ill-formed match…
guitargeek Jul 14, 2026
495d57c
[cppyy] Do not let the Windows std::endl workaround break the import …
guitargeek Jul 15, 2026
6bf9b6c
[cppyy] Detect cppexec errors from the captured diagnostics [upstream]
guitargeek Jul 18, 2026
16e09ca
[cppyy] Adjust cppyy test expectations for the interop migration [ROO…
aaronj0 Apr 26, 2026
b03ceb4
[pyroot] Exclude canonical std::string from generic pretty-printer [R…
aaronj0 May 1, 2026
4888ada
[Python] Pythonize templated classes cached in namespace [ROOT-patch]
aaronj0 May 21, 2026
806fb94
[pyroot] Refactor RDF Filter/Define callable dispatch [ROOT-patch]
aaronj0 May 21, 2026
0d06000
[ROOT] Use value_type instead of string manipulation to pythonize stl…
aaronj0 May 11, 2026
adb392d
[ROOT][test] Canonical name includes UL suffix for literal [ROOT-patch]
aaronj0 May 11, 2026
1c6facf
[cppyy-backend] Normalize exposed names to cppyy's canonical form [RO…
guitargeek Jul 14, 2026
008c7ce
[roottest] Adapt atlas-datavector template instantiation test to new …
guitargeek Jul 15, 2026
4a88876
[RF] Delete fit objects before continuing in rs401d_FeldmanCousins.py…
guitargeek Jul 16, 2026
fe337d6
[DF][Python] Enable ROOT thread safety on the distributed client [ROO…
guitargeek Jul 17, 2026
197efb1
[misc] Export C++-mangled read-only data from bindexplib [ROOT-patch]
guitargeek Jul 18, 2026
38b5e83
[roottest] Disable python-cling-api on Windows [ROOT-patch]
guitargeek Jul 19, 2026
2e26fec
[tutorials] Disable the fitNormSum Python tutorial test on Windows 32…
guitargeek Jul 19, 2026
7ff6861
[cppinterop] Add Cpp::GetOrForceDefinition and use it in auto-downcast
aaronj0 Aug 3, 2026
79c1270
[cppyy-backend] Move GetSizeOfType null guard to the caller [TEMP-CI-…
aaronj0 Aug 21, 2026
8ee352a
[CPyCppyy] Probe API-based mutable-pointer-ref check [TEMP-CI-PROBE]
aaronj0 Sep 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions bindings/distrdf/python/DistRDF/Backends/Base.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,19 @@ class BaseBackend(ABC):
shared_libraries = set()
strings_to_declare = dict()

def __init__(self):
# Enable ROOT thread safety on the client side. Distributed backends
# drive ROOT from more than one thread in the user's process: besides
# the main thread, the scheduler client (e.g. the Dask IO loop thread)
# deserializes the ROOT result objects coming back from the workers.
# That deserialization goes through the cling interpreter (TClass,
# wrapper compilation, ...), so it can run concurrently with interpreter
# activity on the main thread. Without thread safety enabled the
# unsynchronized access corrupts the interpreter state and leads to
# sporadic crashes. This mirrors the ROOT.EnableThreadSafety() call done
# on the workers in setup_mapper().
ROOT.EnableThreadSafety()

@classmethod
def register_initialization(cls, fun, *args, **kwargs):
"""
Expand Down
31 changes: 21 additions & 10 deletions bindings/pyroot/cppyy/CPyCppyy/include/CPyCppyy/API.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,27 @@
#endif
#include "Python.h"

#define CPYCPPYY_VERSION_HEX 0x010c10
#define CPYCPPYY_VERSION_HEX 0x011200

// Cppyy types
#ifndef CPYCPPYY_INTERNAL

namespace Cpp {
struct DeclRef;
struct TypeRef;
struct FuncRef;
struct ObjectRef;
} // namespace Cpp

namespace Cppyy {
typedef size_t TCppScope_t;
typedef TCppScope_t TCppType_t;
typedef void* TCppEnum_t;
typedef void* TCppObject_t;
typedef intptr_t TCppMethod_t;

typedef size_t TCppIndex_t;
typedef void* TCppFuncAddr_t;
typedef Cpp::DeclRef TCppScope_t;
typedef Cpp::TypeRef TCppType_t;
typedef Cpp::ObjectRef TCppObject_t;
typedef Cpp::FuncRef TCppMethod_t;
typedef size_t TCppIndex_t;
typedef void* TCppFuncAddr_t;
} // namespace Cppyy
#endif

// Bindings
#include "CPyCppyy/CommonDefs.h"
Expand Down Expand Up @@ -123,6 +131,7 @@ class CPYCPPYY_CLASS_EXTERN Converter {

// create a converter based on its full type name and dimensions
CPYCPPYY_EXTERN Converter* CreateConverter(const std::string& name, cdims_t = 0);
CPYCPPYY_EXTERN Converter* CreateConverter(Cppyy::TCppType_t type, cdims_t = 0);

// delete a previously created converter
CPYCPPYY_EXTERN void DestroyConverter(Converter* p);
Expand Down Expand Up @@ -153,6 +162,7 @@ class CPYCPPYY_CLASS_EXTERN Executor {

// create an executor based on its full type name
CPYCPPYY_EXTERN Executor* CreateExecutor(const std::string& name, cdims_t = 0);
CPYCPPYY_EXTERN Executor* CreateExecutor(Cppyy::TCppType_t type, cdims_t = 0);

// delete a previously created executor
CPYCPPYY_EXTERN void DestroyConverter(Converter* p);
Expand Down Expand Up @@ -183,7 +193,8 @@ CPYCPPYY_EXTERN void* Instance_AsVoidPtr(PyObject* pyobject);
// void* to C++ Instance (python object proxy) conversion, returns a new reference
CPYCPPYY_EXTERN PyObject* Instance_FromVoidPtr(
void* addr, const std::string& classname, bool python_owns = false);

CPYCPPYY_EXTERN PyObject* Instance_FromVoidPtr(
void* addr, Cppyy::TCppScope_t klass_scope, bool python_owns = false);
// type verifiers for C++ Scope
CPYCPPYY_EXTERN bool Scope_Check(PyObject* pyobject);
CPYCPPYY_EXTERN bool Scope_CheckExact(PyObject* pyobject);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,29 @@
#ifdef _MSC_VER
// Windows requires symbols to be explicitly exported
#define CPYCPPYY_EXPORT extern __declspec(dllexport)
#define CPYCPPYY_IMPORT extern __declspec(dllimport)
#define CPYCPPYY_CLASS_EXPORT __declspec(dllexport)

// CPYCPPYY_EXTERN is dual use in the public API
#ifndef CPYCPPYY_INTERNAL
#define CPYCPPYY_EXTERN extern __declspec(dllexport)
#define CPYCPPYY_CLASS_EXTERN __declspec(dllexport)
#else
#define CPYCPPYY_EXTERN extern
#define CPYCPPYY_CLASS_EXTERN
#define CPYCPPYY_EXTERN extern __declspec(dllimport)
#define CPYCPPYY_CLASS_EXTERN __declspec(dllimport)
#endif

#define CPYCPPYY_STATIC

#else
// Linux, Mac, etc.
#define CPYCPPYY_EXPORT extern
#define CPYCPPYY_IMPORT extern
#define CPYCPPYY_CLASS_EXPORT
#define CPYCPPYY_EXTERN extern
#define CPYCPPYY_CLASS_EXTERN
#define CPYCPPYY_STATIC static

#endif

#define CPYCPPYY_IMPORT extern

#endif // !CPYCPPYY_COMMONDEFS_H
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,16 @@

// Bindings
#include "CPyCppyy/CommonDefs.h"

#include <Python.h>

namespace CPyCppyy {
class PythonGILRAII {
PyGILState_STATE state;

public:
PythonGILRAII() : state(PyGILState_Ensure()) {}
~PythonGILRAII() { PyGILState_Release(state); }
};

class CPYCPPYY_CLASS_EXTERN DispatchPtr {
public:
Expand Down
66 changes: 42 additions & 24 deletions bindings/pyroot/cppyy/CPyCppyy/src/API.cxx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
// Bindings
#include "CPyCppyy.h"
#include "Cppyy.h"
#define CPYCPPYY_INTERNAL 1
#include "CPyCppyy/API.h"
#undef CPYCPPYY_INTERNAL

#include "CPPInstance.h"
#include "CPPOverload.h"
#include "CPPScope.h"
#include "CPyCppyy/DispatchPtr.h"
#include "ProxyWrappers.h"
#include "PyStrings.h"

Expand Down Expand Up @@ -46,22 +48,10 @@ static bool Initialize()

if (!Py_IsInitialized()) {
// this happens if Cling comes in first
#if PY_VERSION_HEX < 0x03020000
PyEval_InitThreads();
#endif
#if PY_VERSION_HEX < 0x03080000
Py_Initialize();
#else
PyConfig config;
PyConfig_InitPythonConfig(&config);
PyConfig_SetString(&config, &config.program_name, L"cppyy");
Py_InitializeFromConfig(&config);
#endif
#if PY_VERSION_HEX >= 0x03020000
#if PY_VERSION_HEX < 0x03090000
PyEval_InitThreads();
#endif
#endif

// try again to see if the interpreter is initialized
if (!Py_IsInitialized()) {
Expand All @@ -70,15 +60,6 @@ static bool Initialize()
return false;
}

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

// Make sure the cppyy extension module is imported, as this is what runs the
Expand All @@ -88,9 +69,10 @@ static bool Initialize()
if (!cppyymod)
return false;
Py_DECREF(cppyymod);
}
}

if (!gMainDict) {
CPyCppyy::PythonGILRAII python_gil_raii;
// retrieve the main dictionary
gMainDict = PyModule_GetDict(
PyImport_AddModule(const_cast<char*>("__main__")));
Expand All @@ -116,7 +98,7 @@ std::string CPyCppyy::Instance_GetScopedFinalName(PyObject* pyobject)
return "";
}

Cppyy::TCppType_t pyobjectClass = ((CPPInstance *)pyobject)->ObjectIsA();
Cppyy::TCppScope_t pyobjectClass = ((CPPInstance *)pyobject)->ObjectIsA();
return Cppyy::GetScopedFinalName(pyobjectClass);
}

Expand All @@ -127,6 +109,8 @@ void* CPyCppyy::Instance_AsVoidPtr(PyObject* pyobject)
if (!Initialize())
return nullptr;

PythonGILRAII python_gil_raii;

// check validity of cast
if (!CPPInstance_Check(pyobject))
return nullptr;
Expand All @@ -143,6 +127,8 @@ PyObject* CPyCppyy::Instance_FromVoidPtr(
if (!Initialize())
return nullptr;

PythonGILRAII python_gil_raii;

// perform cast (the call will check TClass and addr, and set python errors)
PyObject* pyobject = BindCppObjectNoCast(addr, Cppyy::GetScope(classname), false);

Expand All @@ -153,6 +139,25 @@ PyObject* CPyCppyy::Instance_FromVoidPtr(
return pyobject;
}

//-----------------------------------------------------------------------------
PyObject* CPyCppyy::Instance_FromVoidPtr(
void* addr, Cppyy::TCppScope_t klass_scope, bool python_owns)
{
// Bind the addr to a python object of class defined by classname.
if (!Initialize())
return nullptr;

PythonGILRAII python_gil_raii;

// perform cast (the call will check TClass and addr, and set python errors)
PyObject* pyobject = BindCppObjectNoCast(addr, klass_scope, false);

// give ownership, for ref-counting, to the python side, if so requested
if (python_owns && CPPInstance_Check(pyobject))
((CPPInstance*)pyobject)->PythonOwns();

return pyobject;
}
namespace CPyCppyy {
// version with C type arguments only for use with Numba
PyObject* Instance_FromVoidPtr(void* addr, const char* classname, int python_owns) {
Expand All @@ -167,6 +172,7 @@ bool CPyCppyy::Scope_Check(PyObject* pyobject)
if (!Initialize())
return false;

PythonGILRAII python_gil_raii;
return CPPScope_Check(pyobject);
}

Expand All @@ -177,6 +183,7 @@ bool CPyCppyy::Scope_CheckExact(PyObject* pyobject)
if (!Initialize())
return false;

PythonGILRAII python_gil_raii;
return CPPScope_CheckExact(pyobject);
}

Expand All @@ -187,6 +194,7 @@ bool CPyCppyy::Instance_Check(PyObject* pyobject)
if (!Initialize())
return false;

PythonGILRAII python_gil_raii;
// detailed walk through inheritance hierarchy
return CPPInstance_Check(pyobject);
}
Expand All @@ -198,6 +206,7 @@ bool CPyCppyy::Instance_CheckExact(PyObject* pyobject)
if (!Initialize())
return false;

PythonGILRAII python_gil_raii;
// direct pointer comparison of type member
return CPPInstance_CheckExact(pyobject);
}
Expand Down Expand Up @@ -231,6 +240,7 @@ void CPyCppyy::Instance_SetCppOwns(PyObject* pyobject)
//-----------------------------------------------------------------------------
bool CPyCppyy::Sequence_Check(PyObject* pyobject)
{
PythonGILRAII python_gil_raii;
// Extends on PySequence_Check() to determine whether an object can be iterated
// over (technically, all objects can b/c of C++ pointer arithmetic, hence this
// check isn't 100% accurate, but neither is PySequence_Check()).
Expand Down Expand Up @@ -264,6 +274,7 @@ bool CPyCppyy::Sequence_Check(PyObject* pyobject)
//-----------------------------------------------------------------------------
bool CPyCppyy::Instance_IsLively(PyObject* pyobject)
{
PythonGILRAII python_gil_raii;
// Test whether the given instance can safely return to C++
if (!CPPInstance_Check(pyobject))
return true; // simply don't know
Expand All @@ -283,6 +294,7 @@ bool CPyCppyy::Overload_Check(PyObject* pyobject)
if (!Initialize())
return false;

PythonGILRAII python_gil_raii;
// detailed walk through inheritance hierarchy
return CPPOverload_Check(pyobject);
}
Expand All @@ -294,6 +306,7 @@ bool CPyCppyy::Overload_CheckExact(PyObject* pyobject)
if (!Initialize())
return false;

PythonGILRAII python_gil_raii;
// direct pointer comparison of type member
return CPPOverload_CheckExact(pyobject);
}
Expand All @@ -311,6 +324,8 @@ bool CPyCppyy::Import(const std::string& mod_name)
if (!Initialize())
return false;

PythonGILRAII python_gil_raii;

PyObject* mod = PyImport_ImportModule(mod_name.c_str());
if (!mod) {
PyErr_Print();
Expand Down Expand Up @@ -370,6 +385,8 @@ void CPyCppyy::ExecScript(const std::string& name, const std::vector<std::string
if (!Initialize())
return;

PythonGILRAII python_gil_raii;

// verify arguments
if (name.empty()) {
std::cerr << "Error: no file name specified." << std::endl;
Expand All @@ -394,7 +411,6 @@ void CPyCppyy::ExecScript(const std::string& name, const std::vector<std::string
// build new argv
const int argc = (int)args.size() + 1;
std::vector<wchar_t*> wargv(argc);

wargv[0] = Py_DecodeLocale(name.c_str(), nullptr);

for (int i = 1; i < argc; ++i) {
Expand Down Expand Up @@ -444,6 +460,7 @@ bool CPyCppyy::Exec(const std::string& cmd)
if (!Initialize())
return false;

PythonGILRAII python_gil_raii;
// execute the command
PyObject* result =
PyRun_String(const_cast<char*>(cmd.c_str()), Py_file_input, gMainDict, gMainDict);
Expand All @@ -465,6 +482,7 @@ void CPyCppyy::Prompt() {
if (!Initialize())
return;

PythonGILRAII python_gil_raii;
// enter i/o interactive mode
PyRun_InteractiveLoop(stdin, const_cast<char*>("\0"));
}
11 changes: 3 additions & 8 deletions bindings/pyroot/cppyy/CPyCppyy/src/CPPClassMethod.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,8 @@


//- public members --------------------------------------------------------------
PyObject* CPyCppyy::CPPClassMethod::Call(CPPInstance*&
#if PY_VERSION_HEX >= 0x03080000
self
#endif
, CPyCppyy_PyArgs_t args, size_t nargsf, PyObject* kwds, CallContext* ctxt)
PyObject *CPyCppyy::CPPClassMethod::Call(CPPInstance *&self, CPyCppyy_PyArgs_t args,
size_t nargsf, PyObject *kwds, CallContext *ctxt)
{
// preliminary check in case keywords are accidently used (they are ignored otherwise)
if (kwds && ((PyDict_Check(kwds) && PyDict_Size(kwds)) ||
Expand All @@ -23,7 +20,6 @@ PyObject* CPyCppyy::CPPClassMethod::Call(CPPInstance*&
return nullptr;

// translate the arguments
#if PY_VERSION_HEX >= 0x03080000
// TODO: The following is not robust and should be revisited e.g. by making CPPOverloads
// that have only CPPClassMethods be true Python classmethods? Note that the original
// implementation wasn't 100% correct either (e.g. static size() mapped to len()).
Expand All @@ -35,12 +31,11 @@ PyObject* CPyCppyy::CPPClassMethod::Call(CPPInstance*&
if ((!self || (PyObject*)self == Py_None) && nargs) {
PyObject* arg0 = CPyCppyy_PyArgs_GET_ITEM(args, 0);
if (CPPInstance_Check(arg0) && fArgsRequired <= nargs - 1 &&
Cppyy::IsSubtype(reinterpret_cast<CPPInstance *>(arg0)->ObjectIsA(), GetScope())) {
Cppyy::IsSubclass(reinterpret_cast<CPPInstance *>(arg0)->ObjectIsA(), GetScope())) {
args += 1; // drops first argument
nargsf -= 1;
}
}
#endif

if (!this->ConvertAndSetArgs(args, nargsf, ctxt))
return nullptr;
Expand Down
Loading
Loading