Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
113 commits
Select commit Hold shift + click to select a range
0eb1e26
[cppinterop] Add Cling-specific RAII, lookup and dispatch patches [u…
aaronj0 Apr 23, 2026
875bcab
[cppinterop] Fix GetEnumConstantValue when value can't be within int6…
aaronj0 May 11, 2026
9421462
[cppinterop] Fix JitCall codegen for deleted copy ctor in args [upstr…
aaronj0 May 11, 2026
f64a785
[cppinterop] Use canonical return type in wrapper codegen [upstream]
aaronj0 May 21, 2026
df08200
[cppyy-backend] Replace clingwrapper with compres forks [fork-baseline]
aaronj0 Apr 23, 2026
ebfa42f
[cppyy-backend] fix GetActualClass for null [upstream]
aaronj0 May 11, 2026
17face7
[cppyy-backend] Pass CPPINTEROP_DIR directly to AddIncludePath [ROOT-…
aaronj0 May 19, 2026
cbceb18
[cppyy-backend] Apply ROOT patches on compres fork baseline [ROOT-pa…
aaronj0 Apr 23, 2026
1dc12a1
[cppyy-backend] Stage CppInterOp headers via etc/cppinterop [ROOT-patch]
aaronj0 May 19, 2026
f8dd5e7
[cppyy] Replace frontend with compres forks [fork-baseline]
aaronj0 Apr 24, 2026
2dbc6b0
[cppyy] Use qualified complete name for basic_string<char> NPOS check…
aaronj0 Apr 30, 2026
1712021
[cppyy] Apply ROOT-specific patches [ROOT-patch]
aaronj0 Apr 24, 2026
6b31129
[CPyCppyy] Replace with compres forks [fork-baseline]
aaronj0 Apr 23, 2026
d621074
[CPyCppyy] Refactor CallContext policy system, add Py 3.13 guard [up…
aaronj0 Apr 24, 2026
5455c37
[CPyCppyy] Add converters/low-level views for fixed width integers […
aaronj0 Apr 24, 2026
d431425
[CPyCppyy] Fix typos, call GetActualClass in instance cast_actual [u…
aaronj0 Apr 23, 2026
8cd6d09
[CPyCppyy] Apply memory policy refactor to CPPOverload.cxx [upstream]
aaronj0 Apr 23, 2026
2d2d56d
[CPyCppyy] Add CStringArrayConverter::ToMemory and buffer helper [up…
aaronj0 Apr 24, 2026
f5c3617
[CPyCppyy] Collapse CPyCppyyModule policy setters into a macro [upst…
aaronj0 Apr 24, 2026
5604b11
[CPyCppyy] Use CallContext flag for implicit conversion check [upstr…
aaronj0 Apr 23, 2026
5337358
[CPyCppyy] Pythonize: fix __iadd__ return and disable buggy __array__…
aaronj0 Apr 24, 2026
130d102
[CPyCppyy] Use complete basic_string<char> name with default template…
aaronj0 Apr 30, 2026
108949c
[CPyCppyy] Match function-pointer overloads via TCppType_t [upstream]
aaronj0 May 4, 2026
e585dae
[CPyCppyy] declare gException, drop CPYCPPYY_IMPORT from CPPInstance …
aaronj0 Apr 24, 2026
285b562
[CPyCppyy] Add more converter/executor name aliases [ROOT-patch]
aaronj0 Apr 24, 2026
6f08d74
[CPyCppyy] Rename PyInit_libcppyy to Init for ROOT module split [ROO…
aaronj0 Apr 24, 2026
64affb2
[CPyCppyy] Pythonize: add std::span support and no-std wstring aliase…
aaronj0 Apr 24, 2026
e7bc3d4
[CPyCppyy] Add __template_args__ and signature-plus-template overload…
aaronj0 Apr 23, 2026
985a8d7
[CPyCppyy] Always convert returned to Python string [ROOT-patch]
aaronj0 May 1, 2026
d4bd186
[CPyCppyy] Fix false addition of STLSequenceIter for pointer return-t…
aaronj0 May 3, 2026
66f0cee
[cppyy] Newly enabled tests in ROOT by CppInterOp [ROOT-patch]
aaronj0 Apr 26, 2026
d955a65
[pyroot] Exclude canonical std::string from generic pretty-printer [R…
aaronj0 May 1, 2026
4cdfcc0
[Python] Pythonize templated classes cached in namespace [ROOT-patch]
aaronj0 May 21, 2026
37ee0ee
[pyroot] Refactor RDF Filter/Define callable dispatch [ROOT-patch]
aaronj0 May 21, 2026
bb4f206
[ROOT] Use value_type instead of string manipulation to pythonize stl…
aaronj0 May 11, 2026
57b9d8d
[ROOT][test] Canonical name includes UL suffix for literal
aaronj0 May 11, 2026
9ff984a
[cppinterop] Null-guard GetClassTemplateInstantiationArgs [upstream]
aaronj0 Jul 11, 2026
8b62f8b
[cppyy-backend] Skip trampoline on null instantiation scope [upstream]
aaronj0 Jul 11, 2026
578a8e2
[cppyy] Serialize CppInterOp calls with ROOT's interpreter lock
guitargeek Jul 14, 2026
da7525c
[cppinterop] Use `::new` in wrappers that placement-new into a caller…
guitargeek Jul 14, 2026
5f68af0
[CPyCppyy] Restore support for non-const void*& arguments [upstream]
guitargeek Jul 14, 2026
1750380
[CPyCppyy] Cache anonymous-enum constant values in CPPDataMember [ups…
guitargeek Jul 14, 2026
c36a5e2
[cppyy-backend] Resolve qualified names relative to a parent scope
guitargeek Jul 14, 2026
9c675de
[cppinterop] Keep template arguments qualified in GetCompleteName [up…
guitargeek Jul 14, 2026
99b12f2
[cppyy] Remove old patches and patching script for cppyy
guitargeek Jul 14, 2026
caea0ec
[cppyy-backend] Fall back to per-candidate template instantiation in …
guitargeek Jul 14, 2026
a043b80
[cppyy-backend] Filter deleted functions from Python-visible overload…
guitargeek Jul 14, 2026
72c7895
[cppinterop] Cycle through ambiguous lookups in ExistsFunctionTemplat…
guitargeek Jul 14, 2026
f0ee75d
[cppinterop] Compile call wrappers without access control [upstream]
guitargeek Jul 14, 2026
949997b
[CPyCppyy] Exempt T* const& from the mutable pointer-reference ban
guitargeek Jul 14, 2026
30fee57
[cppyy-backend] Perform type lookups from within the parent namespace
guitargeek Jul 14, 2026
65d5c9e
[CPyCppyy] Raise TypeError when a C++ name cannot be constructed
guitargeek Jul 14, 2026
8b95437
[cppinterop] Do not expose inherited special-member constructors [ups…
guitargeek Jul 14, 2026
952c82c
[cppinterop] Use the defining declaration's type for unbounded arrays…
guitargeek Jul 14, 2026
032b490
[cppinterop] Evaluate inline variables that exist in no library [upst…
guitargeek Jul 14, 2026
0493a9a
[CPyCppyy] Re-enable __array__ for vectors of non-class element types
guitargeek Jul 14, 2026
25b0266
[cppyy-backend] Normalize exposed names to cppyy's canonical form
guitargeek Jul 14, 2026
eae3fbe
[cppinterop] Reject ill-formed instantiations in BestOverloadFunction…
guitargeek Jul 14, 2026
c5f39e4
[cppyy-backend] Resolve cppyy.gbl.gROOT to its underlying variable
guitargeek Jul 14, 2026
d675f68
[CPyCppyy] Only pythonize size() as __len__ for integer-sized containers
guitargeek Jul 14, 2026
1b0d818
[cppinterop] Make IsAbstract safe for classes without a definition [u…
guitargeek Jul 14, 2026
c7980dc
[CPyCppyy] Auto-downcast polymorphic pointers read from memory
guitargeek Jul 14, 2026
7962dfb
[cppyy-backend] Resolve template args via enclosing namespaces of the…
guitargeek Jul 15, 2026
d91ba8b
[CPyCppyy] Fix compiler warnings
guitargeek Jul 15, 2026
e6d9682
[cppyy-backend] Fix compiler warnings
guitargeek Jul 15, 2026
bf87afc
[roottest] Adapt atlas-datavector template instantiation test to new …
guitargeek Jul 15, 2026
a094e18
[CPyCppyy] Do not declare the Cppyy API dllimport on Windows
guitargeek Jul 15, 2026
7c3e1c1
[CPyCppyy] Retry template lookup with 2-tuples typed as std::pair
guitargeek Jul 15, 2026
1de15b3
[cppyy-backend] Match basic_string names robustly in operator type remap
guitargeek Jul 15, 2026
08f5c71
[cppinterop] Open a transaction before lookups that may deserialize […
guitargeek Jul 15, 2026
db5879f
[cppyy] Do not let the Windows std::endl workaround break the import
guitargeek Jul 15, 2026
a2cb301
[cppinterop] Search base classes in GetNamed for class scopes [upstream]
guitargeek Jul 15, 2026
04d0948
[CPyCppyy] Type Python complex as std::complex<double> in template args
guitargeek Jul 15, 2026
ff8abb2
[clang] Honor SuppressInlineNamespaceMode::All in the type printer
guitargeek Jul 16, 2026
11c109b
[cppinterop] Print type and scope names platform-independently [upstr…
guitargeek Jul 16, 2026
10341ee
[cppyy] Toggle tests that are now failing or now passing
guitargeek Jul 15, 2026
5791513
[pyroot] Do not retry a failed _finalSetup on every attribute access
guitargeek Jul 16, 2026
996000d
[cppyy-backend] Fix GetActualClass on Windows; add JIT-call tracing
guitargeek Jul 16, 2026
121b6d5
[cppinterop] Guard GetSizeOfType against a null type [upstream]
guitargeek Jul 16, 2026
102425e
[cppyy-backend] Do not call with an unsizable return buffer in CallO
guitargeek Jul 16, 2026
b58ddec
[RF] Delete fit objects before continuing in rs401d_FeldmanCousins.py
guitargeek Jul 16, 2026
77e873b
[pyroot] Do not stringify C++ instances when scanning for used classes
guitargeek Jul 17, 2026
36105cf
[pyroot] Clarify the used-class scan in _find_used_classes (NFC)
guitargeek Jul 17, 2026
84a4cd8
[cppinterop] Skip linkage specs when walking up parent scopes [upstream]
guitargeek Jul 17, 2026
83d7328
[cppinterop] Use IsCopyConstructorDeleted for by-value args in calls …
guitargeek Jul 17, 2026
0c7445d
[cppinterop] Do not overflow std::stoul on huge enum values [upstream]
guitargeek Jul 17, 2026
5cc1133
[cling] Never resolve JIT symbols against legacy MSVC runtimes
guitargeek Jul 17, 2026
f68e997
[cppyy-backend] Instantiate templated operator-> in smart-ptr detection
guitargeek Jul 17, 2026
2fb14b6
[cppinterop] Do not crash on globals with no definition in the AST [u…
guitargeek Jul 17, 2026
87d9c6d
[cppyy] Do not attempt implicit conversion to stdlib implementation d…
guitargeek Jul 17, 2026
c0f83cf
[cppyy] TEMP: diagnose bindings to nameless scopes
guitargeek Jul 16, 2026
f21fa70
[cppyy] TEMP: print Python stack on failed _Swc_base implicit conversion
guitargeek Jul 16, 2026
ea5735c
[cppyy] TEMP: report unexpected resolution of std::string in STLStrin…
guitargeek Jul 16, 2026
2c23208
[cppyy] TEMP: Windows-only tracing to localize test19 access violation
guitargeek Jul 17, 2026
8ced3e5
[cppyy] TEMP: trace wrapper branches with class-type default arguments
guitargeek Jul 17, 2026
ffe4880
[cppyy] Allow implicit conversion between same-template stdlib details
guitargeek Jul 17, 2026
79e4f0b
[cppyy-backend] Do not autocast iostream classes in GetActualClass
guitargeek Jul 17, 2026
88e9264
[cppinterop] Return enum constant values as int64_t [upstream]
guitargeek Jul 17, 2026
aaf8f12
[cppinterop] Emit unexported globals whose initializer is known [upst…
guitargeek Jul 17, 2026
179e404
[cppyy] TEMP: report method enumeration for smart pointer classes
guitargeek Jul 17, 2026
91d24c1
[DF][Python] Enable ROOT thread safety on the distributed client
guitargeek Jul 17, 2026
3e7d005
[cppyy] Remove temporary callee-side prints from tests
guitargeek Jul 18, 2026
2a8a606
[cppinterop] Remove temporary wrapper-branch tracing
guitargeek Jul 18, 2026
79c103a
[cppinterop] Report parse errors from Cpp::Process [upstream]
guitargeek Jul 18, 2026
91d266d
[cppinterop] Materialize const array values host-side in GetVariableO…
guitargeek Jul 18, 2026
19744eb
[cppyy] TEMP: extend Windows diagnostics for the remaining CI failures
guitargeek Jul 18, 2026
4a986e6
[cppyy] TEMP: fix MSVC compilation of the smart pointer method diag
guitargeek Jul 18, 2026
3e1d247
[cppyy] Detect cppexec errors from the captured diagnostics
guitargeek Jul 18, 2026
9e2e647
[cppinterop] Remove ineffective error trap from Cpp::Process [upstream]
guitargeek Jul 18, 2026
6dfe1d6
[cppinterop] Only instantiate variables that have a pattern [upstream]
guitargeek Jul 18, 2026
37b48f7
[misc] Export named read-only data from bindexplib
guitargeek Jul 18, 2026
ec8e902
[cppyy] TEMP: windows_7 diagnostics for the remaining CI failures
guitargeek Jul 18, 2026
900a1b5
[misc] Restrict bindexplib read-only data exports to C++-mangled names
guitargeek Jul 18, 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
65 changes: 41 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,21 +60,12 @@ 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

// force loading of the cppyy module
PyRun_SimpleString(const_cast<char*>("import cppyy"));
}

if (!gMainDict) {
CPyCppyy::PythonGILRAII python_gil_raii;
// retrieve the main dictionary
gMainDict = PyModule_GetDict(
PyImport_AddModule(const_cast<char*>("__main__")));
Expand All @@ -110,7 +91,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 @@ -121,6 +102,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 @@ -137,6 +120,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 @@ -147,6 +132,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 @@ -161,6 +165,7 @@ bool CPyCppyy::Scope_Check(PyObject* pyobject)
if (!Initialize())
return false;

PythonGILRAII python_gil_raii;
return CPPScope_Check(pyobject);
}

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

PythonGILRAII python_gil_raii;
return CPPScope_CheckExact(pyobject);
}

Expand All @@ -181,6 +187,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 @@ -192,6 +199,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 @@ -225,6 +233,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 @@ -258,6 +267,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 @@ -277,6 +287,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 @@ -288,6 +299,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 @@ -305,6 +317,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 @@ -364,6 +378,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 @@ -388,7 +404,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 @@ -438,6 +453,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 @@ -459,6 +475,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