94 PyGILRAII thePyGILRAII;
97 PyObject *modules = PySys_GetObject(
const_cast<char *
>(
"modules"));
99 PyObject *keys = PyDict_Keys(modules);
100 Bool_t isModule = PySequence_Contains(keys, pyname);
111 std::ostringstream nsCode;
112 nsCode <<
"namespace " <<
name <<
" {\n";
115 PyObject *bases = PyUnicode_FromString(
"__bases__");
116 PyObject *mod = PyDict_GetItemString(modules,
const_cast<char *
>(
name));
117 PyObject *dct = PyModule_GetDict(mod);
118 keys = PyDict_Keys(dct);
120 for (
int i = 0; i < PyList_Size(keys); ++i) {
122 PyObject *key = PyList_GetItem(keys, i);
123 PyObject *attr = PyDict_GetItem(dct, key);
126 if (PyCallable_Check(attr) && !(PyType_Check(attr) || PyObject_HasAttr(attr, bases))) {
127 const char *func_name = PyUnicode_AsUTF8AndSize(key,
nullptr);
136 PyObject_GetOptionalAttrString(attr, (
char *)
"func_code", &func_code);
137 PyObject *var_names = func_code ? PyObject_GetAttrString(func_code, (
char *)
"co_varnames") : NULL;
138 int nVars = var_names ? PyTuple_Size(var_names) : 0 ;
141 Py_DecRef(var_names);
142 Py_DecRef(func_code);
144 nsCode <<
" TPyReturn " << func_name <<
"(";
145 for (
int ivar = 0; ivar < nVars; ++ivar) {
146 nsCode <<
"const TPyArg& a" << ivar;
147 if (ivar != nVars - 1)
151 nsCode <<
" std::vector<TPyArg> v; v.reserve(" << nVars <<
");\n";
154 for (
int ivar = 0; ivar < nVars; ++ivar)
155 nsCode <<
" v.push_back(a" << ivar <<
");\n";
158 nsCode <<
" return TPyReturn(TPyArg::CallMethod((PyObject*)" << std::showbase << (uintptr_t)attr <<
", v)); }\n";
177 std::string clName =
name;
178 std::string::size_type pos = clName.rfind(
'.');
180 if (pos == std::string::npos)
183 std::string mdName = clName.substr(0, pos);
184 clName = clName.substr(pos + 1, std::string::npos);
187 Bool_t useNS =
gROOT->GetListOfClasses()->FindObject(mdName.c_str()) != 0;
196 PyObject *mod = PyImport_AddModule(
const_cast<char *
>(mdName.c_str()));
203 PyObject *pyclass = PyDict_GetItemString(PyModule_GetDict(mod),
const_cast<char *
>(clName.c_str()));
213 PyObject *attrs = PyObject_Dir(pyclass);
221 std::ostringstream proxyCode;
223 proxyCode <<
"namespace " << mdName <<
" { ";
224 proxyCode <<
"class " << clName <<
" {\nprivate:\n PyObject* fPyObject;\npublic:\n";
228 for (
int i = 0; i < PyList_Size(attrs); ++i) {
229 PyObject *label = PyList_GetItem(attrs, i);
231 PyObject *attr = PyObject_GetAttr(pyclass, label);
234 if (PyCallable_Check(attr)) {
235 const char *mtNameCStr = PyUnicode_AsUTF8AndSize(label,
nullptr);
239 std::string mtName = mtNameCStr;
241 if (mtName ==
"__del__") {
242 hasDestructor =
kTRUE;
243 proxyCode <<
" ~" << clName <<
"() { TPyArg::CallDestructor(fPyObject); }\n";
247 Bool_t isConstructor = mtName ==
"__init__";
248 if (!isConstructor && mtName.find(
"__", 0, 2) == 0)
252 PyObject *func_code = PyObject_GetAttrString(attr,
"__code__");
253 PyObject *var_names = func_code ? PyObject_GetAttrString(func_code, (
char *)
"co_varnames") : NULL;
254 if (PyErr_Occurred())
258 var_names ? PyTuple_Size(var_names) - 1 : 0 ;
261 Py_DecRef(var_names);
262 Py_DecRef(func_code);
266 hasConstructor =
kTRUE;
267 proxyCode <<
" " << clName <<
"(";
269 proxyCode <<
" TPyReturn " << mtName <<
"(";
270 for (
int ivar = 0; ivar < nVars; ++ivar) {
271 proxyCode <<
"const TPyArg& a" << ivar;
272 if (ivar != nVars - 1)
275 proxyCode <<
") {\n";
276 proxyCode <<
" std::vector<TPyArg> v; v.reserve(" << nVars + (isConstructor ? 0 : 1) <<
");\n";
280 proxyCode <<
" v.push_back(fPyObject);\n";
283 for (
int ivar = 0; ivar < nVars; ++ivar)
284 proxyCode <<
" v.push_back(a" << ivar <<
");\n";
288 proxyCode <<
" return TPyReturn(TPyArg::CallMethod((PyObject*)" << std::showbase << (uintptr_t)attr <<
", v))";
290 proxyCode <<
" TPyArg::CallConstructor(fPyObject, (PyObject*)" << std::showbase << (uintptr_t)pyclass <<
", v)";
291 proxyCode <<
";\n }\n";
300 proxyCode <<
" " << clName <<
"() {\n TPyArg::CallConstructor(fPyObject, (PyObject*)" << std::showbase << (uintptr_t)pyclass
304 proxyCode <<
" ~" << clName <<
"() { TPyArg::CallDestructor(fPyObject); }\n";
307 proxyCode <<
" " << clName <<
"(const " << clName <<
"&) = delete;\n";
308 proxyCode <<
" " << clName <<
"& operator=(const " << clName <<
"&) = delete;\n";
324 TClass *klass =
new TClass(useNS ? (mdName +
"::" + clName).c_str() : clName.c_str(), silent);