17#include "TPyClassGenerator.h"
102class CachedPyString {
105 CachedPyString(
const char *
name) : fObj{PyUnicode_FromString(
name)} {}
107 CachedPyString(CachedPyString
const &) =
delete;
108 CachedPyString(CachedPyString &&) =
delete;
109 CachedPyString &
operator=(CachedPyString
const &) =
delete;
110 CachedPyString &
operator=(CachedPyString &&) =
delete;
112 ~CachedPyString() { Py_DECREF(fObj); }
120PyThreadState *mainThreadState;
125 PyGILState_STATE m_GILState;
128 PyGILRAII() : m_GILState(PyGILState_Ensure()) {}
129 ~PyGILRAII() { PyGILState_Release(m_GILState); }
140 static std::mutex initMutex;
141 const std::lock_guard<std::mutex> lock(initMutex);
147 if (!Py_IsInitialized()) {
149#if PY_VERSION_HEX < 0x03020000
150 PyEval_InitThreads();
154#if PY_VERSION_HEX < 0x03000000
155 char *argv[] = {
const_cast<char *
>(
"root")};
157 wchar_t *argv[] = {
const_cast<wchar_t *
>(L
"root")};
159 int argc =
sizeof(argv) /
sizeof(argv[0]);
160#if PY_VERSION_HEX < 0x030b0000
166 PyConfig_InitPythonConfig(&config);
168 status = PyConfig_SetArgv(&config, argc, argv);
169 if (PyStatus_Exception(status)) {
170 PyConfig_Clear(&config);
171 std::cerr <<
"Error when setting command line arguments." << std::endl;
175 status = Py_InitializeFromConfig(&config);
176 if (PyStatus_Exception(status)) {
177 PyConfig_Clear(&config);
178 std::cerr <<
"Error when initializing Python." << std::endl;
181 PyConfig_Clear(&config);
183#if PY_VERSION_HEX >= 0x03020000
184#if PY_VERSION_HEX < 0x03090000
185 PyEval_InitThreads();
190 if (!Py_IsInitialized()) {
192 std::cerr <<
"Error: python has not been intialized; returning." << std::endl;
196#if PY_VERSION_HEX < 0x030b0000
197 PySys_SetArgv(argc, argv);
200 mainThreadState = PyEval_SaveThread();
208 const int ret = PyRun_SimpleString(
const_cast<char *
>(
"import ROOT"));
210 std::cerr <<
"Error: import ROOT failed, check your PYTHONPATH environmental variable." << std::endl;
217 gMainDict = PyModule_GetDict(PyImport_AddModule(
const_cast<char *
>(
"__main__")));
229 isInitialized =
kTRUE;
252 PyObject *modNameObj = PyUnicode_FromString(mod_name);
253 PyObject *mod = PyImport_GetModule(modNameObj);
254 PyObject *dct = PyModule_GetDict(mod);
256 CachedPyString basesStr{
"__bases__"};
257 CachedPyString cppNameStr{
"__cpp_name__"};
258 CachedPyString nameStr{
"__name__"};
261 PyObject *values = PyDict_Values(dct);
262 for (
int i = 0; i < PyList_GET_SIZE(values); ++i) {
267 if (PyType_Check(
value) || PyObject_HasAttr(
value, basesStr.obj())) {
269 PyObject *pyClName = PyObject_GetAttr(
value, cppNameStr.obj());
271 pyClName = PyObject_GetAttr(
value, nameStr.obj());
274 if (PyErr_Occurred())
278 std::string fullname = mod_name;
280 fullname += PyUnicode_AsUTF8(pyClName);
285 Py_XDECREF(pyClName);
293 Py_DECREF(modNameObj);
295 if (PyErr_Occurred())
317#if PY_VERSION_HEX < 0x03000000
318 Exec((std::string(
"execfile(\"") +
name +
"\")").c_str());
320 Exec((std::string(
"__pyroot_f = open(\"") +
name +
322 "exec(__pyroot_f.read()); "
323 "__pyroot_f.close(); del __pyroot_f")
330 CachedPyString basesStr{
"__bases__"};
331 CachedPyString moduleStr{
"__module__"};
332 CachedPyString nameStr{
"__name__"};
335 for (
int i = 0; i < PyList_GET_SIZE(current); ++i) {
339 if (!PySequence_Contains(old,
value)) {
341 if (PyType_Check(
value) || PyObject_HasAttr(
value, basesStr.obj())) {
343 PyObject *pyModName = PyObject_GetAttr(
value, moduleStr.obj());
346 if (PyErr_Occurred())
351 if ((pyModName && pyClName) && ((PyUnicode_CheckExact(pyModName) && PyUnicode_CheckExact(pyClName)) ||
352 (PyUnicode_Check(pyModName) && PyUnicode_Check(pyClName)))) {
354 std::string fullname = PyUnicode_AsUTF8(pyModName);
356 fullname += PyUnicode_AsUTF8(pyClName);
362 Py_XDECREF(pyClName);
363 Py_XDECREF(pyModName);
392 std::cerr <<
"Error: no file name specified." << std::endl;
396 std::vector<std::string> args(argc);
397 for (
int i = 0; i < argc; ++i) {
433 std::stringstream command;
438 command <<
"; ROOT.Internal.SwapWithObjAtAddr['std::any'](" << resultName <<
", "
439 <<
reinterpret_cast<std::intptr_t
>(
result) <<
")";
444 PyRun_String(
const_cast<char *
>(command.str().c_str()), Py_file_input,
gMainDict,
gMainDict);
447 if (pyObjectResult) {
448 Py_DECREF(pyObjectResult);
473 Bool_t bOk = PyDict_SetItemString(
gMainDict,
const_cast<char *
>(label), bound) == 0;
497 PyRun_InteractiveLoop(stdin,
const_cast<char *
>(
"\0"));
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
static PyObject * gMainDict
Binding & operator=(OUT(*fun)(void))
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.
Accessing the Python interpreter from C++.
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 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)