17#include "TPyClassGenerator.h"
33 PyGILState_STATE m_GILState;
35 PyGILRAII() : m_GILState(PyGILState_Ensure()) { }
36 ~PyGILRAII() { PyGILState_Release(m_GILState); }
59 PyGILRAII thePyGILRAII;
62 PyObject *modules = PySys_GetObject(
const_cast<char *
>(
"modules"));
64 PyObject *keys = PyDict_Keys(modules);
76 std::ostringstream nsCode;
77 nsCode <<
"namespace " <<
name <<
" {\n";
80 PyObject *mod = PyDict_GetItemString(modules,
const_cast<char *
>(
name));
81 PyObject *dct = PyModule_GetDict(mod);
82 keys = PyDict_Keys(dct);
84 for (
int i = 0; i < PyList_GET_SIZE(keys); ++i) {
85 PyObject *key = PyList_GET_ITEM(keys, i);
88 PyObject *attr = PyDict_GetItem(dct, key);
96 PyObject *func_code = PyObject_GetAttrString(attr, (
char *)
"func_code");
97 PyObject *var_names = func_code ? PyObject_GetAttrString(func_code, (
char *)
"co_varnames") : NULL;
98 int nVars = var_names ? PyTuple_GET_SIZE(var_names) : 0 ;
101 Py_XDECREF(var_names);
102 Py_XDECREF(func_code);
104 nsCode <<
" TPyReturn " << func_name <<
"(";
105 for (
int ivar = 0; ivar < nVars; ++ivar) {
106 nsCode <<
"const TPyArg& a" << ivar;
107 if (ivar != nVars - 1)
111 nsCode <<
" std::vector<TPyArg> v; v.reserve(" << nVars <<
");\n";
114 for (
int ivar = 0; ivar < nVars; ++ivar)
115 nsCode <<
" v.push_back(a" << ivar <<
");\n";
118 nsCode <<
" return TPyReturn(TPyArg::CallMethod((PyObject*)" << (
void *)attr <<
", v)); }\n";
139 std::string clName =
name;
140 std::string::size_type pos = clName.rfind(
'.');
142 if (pos == std::string::npos)
145 std::string mdName = clName.substr(0, pos);
146 clName = clName.substr(pos + 1, std::string::npos);
149 Bool_t useNS =
gROOT->GetListOfClasses()->FindObject(mdName.c_str()) != 0;
158 PyObject *mod = PyImport_AddModule(
const_cast<char *
>(mdName.c_str()));
165 PyObject *pyclass = PyDict_GetItemString(PyModule_GetDict(mod),
const_cast<char *
>(clName.c_str()));
175 PyObject *attrs = PyObject_Dir(pyclass);
183 std::ostringstream proxyCode;
185 proxyCode <<
"namespace " << mdName <<
" { ";
186 proxyCode <<
"class " << clName <<
" {\nprivate:\n PyObject* fPyObject;\npublic:\n";
190 for (
int i = 0; i < PyList_GET_SIZE(attrs); ++i) {
191 PyObject *label = PyList_GET_ITEM(attrs, i);
193 PyObject *attr = PyObject_GetAttr(pyclass, label);
196 if (PyCallable_Check(attr)) {
199 if (mtName ==
"__del__") {
200 hasDestructor =
kTRUE;
201 proxyCode <<
" ~" << clName <<
"() { TPyArg::CallDestructor(fPyObject); }\n";
205 Bool_t isConstructor = mtName ==
"__init__";
206 if (!isConstructor && mtName.find(
"__", 0, 2) == 0)
210#if PY_VERSION_HEX < 0x03000000
211 PyObject *im_func = PyObject_GetAttrString(attr, (
char *)
"im_func");
212 PyObject *func_code = im_func ? PyObject_GetAttrString(im_func, (
char *)
"func_code") : NULL;
214 PyObject *func_code = PyObject_GetAttrString(attr,
"__code__");
216 PyObject *var_names = func_code ? PyObject_GetAttrString(func_code, (
char *)
"co_varnames") : NULL;
217 if (PyErr_Occurred())
221 var_names ? PyTuple_GET_SIZE(var_names) - 1 : 0 ;
224 Py_XDECREF(var_names);
225 Py_XDECREF(func_code);
226#if PY_VERSION_HEX < 0x03000000
232 hasConstructor =
kTRUE;
233 proxyCode <<
" " << clName <<
"(";
235 proxyCode <<
" TPyReturn " << mtName <<
"(";
236 for (
int ivar = 0; ivar < nVars; ++ivar) {
237 proxyCode <<
"const TPyArg& a" << ivar;
238 if (ivar != nVars - 1)
241 proxyCode <<
") {\n";
242 proxyCode <<
" std::vector<TPyArg> v; v.reserve(" << nVars + (isConstructor ? 0 : 1) <<
");\n";
246 proxyCode <<
" v.push_back(fPyObject);\n";
249 for (
int ivar = 0; ivar < nVars; ++ivar)
250 proxyCode <<
" v.push_back(a" << ivar <<
");\n";
254 proxyCode <<
" return TPyReturn(TPyArg::CallMethod((PyObject*)" << (
void *)attr <<
", v))";
256 proxyCode <<
" TPyArg::CallConstructor(fPyObject, (PyObject*)" << (
void *)pyclass <<
", v)";
257 proxyCode <<
";\n }\n";
266 proxyCode <<
" " << clName <<
"() {\n TPyArg::CallConstructor(fPyObject, (PyObject*)" << (
void *)pyclass
270 proxyCode <<
" ~" << clName <<
"() { TPyArg::CallDestructor(fPyObject); }\n";
273 proxyCode <<
" " << clName <<
"(const " << clName <<
"&) = delete;\n";
274 proxyCode <<
" " << clName <<
"& operator=(const " << clName <<
"&) = delete;\n";
290 TClass *klass =
new TClass(useNS ? (mdName +
"::" + clName).c_str() : clName.c_str(), silent);
301 return GetClass(typeinfo.name(), load, silent);
309 return GetClass(typeinfo.name(), load);
#define CPyCppyy_PyText_AsString
#define CPyCppyy_PyText_FromString
TClass instances represent classes, structs and namespaces in the ROOT type system.
static void AddClass(TClass *cl)
static: Add a class to the list and map of classes.
virtual TClass * GetClass(const char *name, Bool_t load)