103PyThreadState *mainThreadState;
108 PyGILState_STATE m_GILState;
111 PyGILRAII() : m_GILState(PyGILState_Ensure()) {}
112 ~PyGILRAII() { PyGILState_Release(m_GILState); }
121using PyObjectRef = std::unique_ptr<PyObject, PyObjDeleter>;
131 static std::mutex initMutex;
132 const std::lock_guard<std::mutex> lock(initMutex);
134 static Bool_t isInitialized =
false;
138 if (!Py_IsInitialized()) {
142 mainThreadState = PyEval_SaveThread();
150 PyObject* rootModule = PyImport_ImportModule(
"ROOT");
157 PyObject* interpreterAttr = PyObject_GetAttrString(rootModule,
"gInterpreter");
158 if (!interpreterAttr) {
160 Py_DecRef(rootModule);
164 Py_DecRef(interpreterAttr);
169 gMainDict = PyModule_GetDict(PyImport_AddModule(
"__main__"));
177 if (PyDict_SetItemString(
gMainDict,
"ROOT", rootModule) != 0) {
179 Py_DecRef(rootModule);
183 Py_DecRef(rootModule);
190 isInitialized =
true;
213 PyObjectRef modNameObj{PyUnicode_FromString(mod_name)};
214 PyObjectRef mod{PyImport_GetModule(modNameObj.get())};
215 PyObject *dct = PyModule_GetDict(mod.get());
217 PyObjectRef basesStr{PyUnicode_FromString(
"__bases__")};
218 PyObjectRef cppNameStr{PyUnicode_FromString(
"__cpp_name__")};
219 PyObjectRef nameStr{PyUnicode_FromString(
"__name__")};
222 PyObjectRef values{PyDict_Values(dct)};
223 for (
int i = 0; i < PyList_Size(values.get()); ++i) {
224 PyObjectRef value{PyList_GetItem(values.get(), i)};
225 Py_IncRef(value.get());
228 if (PyType_Check(value.get()) || PyObject_HasAttr(value.get(), basesStr.get())) {
230 PyObjectRef pyClName{PyObject_GetAttr(value.get(), cppNameStr.get())};
232 if (PyErr_Occurred())
234 pyClName = PyObjectRef{PyObject_GetAttr(value.get(), nameStr.get())};
237 if (PyErr_Occurred())
241 std::string fullname = mod_name;
243 fullname += PyUnicode_AsUTF8AndSize(pyClName.get(),
nullptr);
250 return !PyErr_Occurred();
267 PyObjectRef old{PyDict_Values(
gMainDict)};
271 std::string escapedName;
272 escapedName.reserve(std::char_traits<char>::length(
name));
273 for (
const char *p =
name; *p; ++p) {
275 case '\\': escapedName +=
"\\\\";
break;
276 case '"': escapedName +=
"\\\"";
break;
277 case '\n': escapedName +=
"\\n";
break;
278 case '\r': escapedName +=
"\\r";
break;
279 default: escapedName += *p;
break;
284 Exec((std::string(
"__pyroot_f = open(\"") + escapedName +
286 "exec(__pyroot_f.read()); "
287 "__pyroot_f.close(); del __pyroot_f")
291 PyObjectRef current{PyDict_Values(
gMainDict)};
293 PyObjectRef basesStr{PyUnicode_FromString(
"__bases__")};
294 PyObjectRef moduleStr{PyUnicode_FromString(
"__module__")};
295 PyObjectRef nameStr{PyUnicode_FromString(
"__name__")};
298 for (
int i = 0; i < PyList_Size(current.get()); ++i) {
299 PyObjectRef value{PyList_GetItem(current.get(), i)};
300 Py_IncRef(value.get());
302 if (!PySequence_Contains(old.get(), value.get())) {
304 if (PyType_Check(value.get()) || PyObject_HasAttr(value.get(), basesStr.get())) {
306 PyObjectRef pyModName{PyObject_GetAttr(value.get(), moduleStr.get())};
307 PyObjectRef pyClName{PyObject_GetAttr(value.get(), nameStr.get())};
309 if (PyErr_Occurred())
314 if ((pyModName && pyClName) && ((PyUnicode_CheckExact(pyModName.get()) && PyUnicode_CheckExact(pyClName.get())) ||
315 (PyUnicode_Check(pyModName.get()) && PyUnicode_Check(pyClName.get())))) {
317 std::string fullname = PyUnicode_AsUTF8AndSize(pyModName.get(),
nullptr);
319 fullname += PyUnicode_AsUTF8AndSize(pyClName.get(),
nullptr);
347 std::cerr <<
"Error: no file name specified." << std::endl;
351 std::vector<std::string> args(argc);
352 for (
int i = 0; i < argc; ++i) {
388 std::stringstream command;
393 command <<
"; ROOT.Internal.SwapWithObjAtAddr['std::any'](" << resultName <<
", "
394 <<
reinterpret_cast<std::intptr_t
>(result) <<
")";
bool Bool_t
Boolean (0=false, 1=true) (bool).
static PyObject * gMainDict
TRObject operator()(const T1 &t1) const
TClass instances represent classes, structs and namespaces in the ROOT type system.
TClass * IsA() const override
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
const char * GetName() const override
Returns name of object.
Mother of all ROOT objects.
static void Prompt()
Enter an interactive python session (exit with ^D).
static Bool_t CPPOverload_Check(PyObject *pyobject)
Test whether the type of the given pyobject is of CPPOverload type or any derived type.
static void * CPPInstance_AsVoidPtr(PyObject *pyobject)
Extract the object pointer held by the CPPInstance pyobject.
static void ExecScript(const char *name, int argc=0, const char **argv=nullptr)
Execute a python stand-alone script, with argv CLI arguments.
static Bool_t Import(const char *name)
Import the named python module and create Cling equivalents for its classes and methods.
static Bool_t CPPInstance_CheckExact(PyObject *pyobject)
Test whether the type of the given pyobject is CPPinstance type.
static Bool_t Bind(TObject *object, const char *label)
Bind a ROOT object with, at the python side, the name "label".
static void LoadMacro(const char *name)
Execute the give python script as if it were a macro (effectively an execfile in main),...
static Bool_t Exec(const char *cmd, std::any *result=nullptr, std::string const &resultName="_anyresult")
Executes a Python command within the current Python environment.
static Bool_t CPPOverload_CheckExact(PyObject *pyobject)
Test whether the type of the given pyobject is CPPOverload type.
static Bool_t Initialize()
Initialization method: setup the python interpreter and load the ROOT module.
static Bool_t CPPInstance_Check(PyObject *pyobject)
Test whether the type of the given pyobject is of CPPInstance type or any derived type.
static PyObject * CPPInstance_FromVoidPtr(void *addr, const char *classname, Bool_t python_owns=kFALSE)
Bind the addr to a python object of class defined by classname.
CPYCPPYY_EXTERN bool Instance_CheckExact(PyObject *pyobject)
CPYCPPYY_EXTERN void Prompt()
CPYCPPYY_EXTERN bool Overload_Check(PyObject *pyobject)
CPYCPPYY_EXTERN bool Overload_CheckExact(PyObject *pyobject)
CPYCPPYY_EXTERN bool Import(const std::string &name)
CPYCPPYY_EXTERN void ExecScript(const std::string &name, const std::vector< std::string > &args)
CPYCPPYY_EXTERN bool Instance_Check(PyObject *pyobject)
CPYCPPYY_EXTERN PyObject * Instance_FromVoidPtr(void *addr, const std::string &classname, bool python_owns=false)
CPYCPPYY_EXTERN void * Instance_AsVoidPtr(PyObject *pyobject)
CPYCPPYY_EXTERN bool Scope_Check(PyObject *pyobject)
CPYCPPYY_EXTERN bool Exec(const std::string &cmd)