16#include "TPyClassGenerator.h"
40 PyGILState_STATE m_GILState;
42 PyGILRAII() : m_GILState(PyGILState_Ensure()) { }
43 ~PyGILRAII() { PyGILState_Release(m_GILState); }
66 PyGILRAII thePyGILRAII;
69 PyObject *modules = PySys_GetObject(
const_cast<char *
>(
"modules"));
71 PyObject *keys = PyDict_Keys(modules);
83 std::ostringstream nsCode;
84 nsCode <<
"namespace " <<
name <<
" {\n";
87 PyObject *mod = PyDict_GetItemString(modules,
const_cast<char *
>(
name));
88 PyObject *dct = PyModule_GetDict(mod);
89 keys = PyDict_Keys(dct);
91 for (
int i = 0; i < PyList_GET_SIZE(keys); ++i) {
92 PyObject *key = PyList_GET_ITEM(keys, i);
95 PyObject *attr = PyDict_GetItem(dct, key);
103 PyObject *func_code = PyObject_GetAttrString(attr, (
char *)
"func_code");
104 PyObject *var_names = func_code ? PyObject_GetAttrString(func_code, (
char *)
"co_varnames") : NULL;
105 int nVars = var_names ? PyTuple_GET_SIZE(var_names) : 0 ;
108 Py_XDECREF(var_names);
109 Py_XDECREF(func_code);
111 nsCode <<
" TPyReturn " << func_name <<
"(";
112 for (
int ivar = 0; ivar < nVars; ++ivar) {
113 nsCode <<
"const TPyArg& a" << ivar;
114 if (ivar != nVars - 1)
118 nsCode <<
" std::vector<TPyArg> v; v.reserve(" << nVars <<
");\n";
121 for (
int ivar = 0; ivar < nVars; ++ivar)
122 nsCode <<
" v.push_back(a" << ivar <<
");\n";
125 nsCode <<
" return TPyReturn(TPyArg::CallMethod((PyObject*)" << std::showbase << (uintptr_t)attr <<
", v)); }\n";
146 std::string clName =
name;
147 std::string::size_type pos = clName.rfind(
'.');
149 if (pos == std::string::npos)
152 std::string mdName = clName.substr(0, pos);
153 clName = clName.substr(pos + 1, std::string::npos);
156 Bool_t useNS =
gROOT->GetListOfClasses()->FindObject(mdName.c_str()) != 0;
165 PyObject *mod = PyImport_AddModule(
const_cast<char *
>(mdName.c_str()));
172 PyObject *pyclass = PyDict_GetItemString(PyModule_GetDict(mod),
const_cast<char *
>(clName.c_str()));
182 PyObject *attrs = PyObject_Dir(pyclass);
190 std::ostringstream proxyCode;
192 proxyCode <<
"namespace " << mdName <<
" { ";
193 proxyCode <<
"class " << clName <<
" {\nprivate:\n PyObject* fPyObject;\npublic:\n";
197 for (
int i = 0; i < PyList_GET_SIZE(attrs); ++i) {
198 PyObject *label = PyList_GET_ITEM(attrs, i);
200 PyObject *attr = PyObject_GetAttr(pyclass, label);
203 if (PyCallable_Check(attr)) {
206 if (mtName ==
"__del__") {
207 hasDestructor =
kTRUE;
208 proxyCode <<
" ~" << clName <<
"() { TPyArg::CallDestructor(fPyObject); }\n";
212 Bool_t isConstructor = mtName ==
"__init__";
213 if (!isConstructor && mtName.find(
"__", 0, 2) == 0)
217#if PY_VERSION_HEX < 0x03000000
218 PyObject *im_func = PyObject_GetAttrString(attr, (
char *)
"im_func");
219 PyObject *func_code = im_func ? PyObject_GetAttrString(im_func, (
char *)
"func_code") : NULL;
221 PyObject *func_code = PyObject_GetAttrString(attr,
"__code__");
223 PyObject *var_names = func_code ? PyObject_GetAttrString(func_code, (
char *)
"co_varnames") : NULL;
224 if (PyErr_Occurred())
228 var_names ? PyTuple_GET_SIZE(var_names) - 1 : 0 ;
231 Py_XDECREF(var_names);
232 Py_XDECREF(func_code);
233#if PY_VERSION_HEX < 0x03000000
239 hasConstructor =
kTRUE;
240 proxyCode <<
" " << clName <<
"(";
242 proxyCode <<
" TPyReturn " << mtName <<
"(";
243 for (
int ivar = 0; ivar < nVars; ++ivar) {
244 proxyCode <<
"const TPyArg& a" << ivar;
245 if (ivar != nVars - 1)
248 proxyCode <<
") {\n";
249 proxyCode <<
" std::vector<TPyArg> v; v.reserve(" << nVars + (isConstructor ? 0 : 1) <<
");\n";
253 proxyCode <<
" v.push_back(fPyObject);\n";
256 for (
int ivar = 0; ivar < nVars; ++ivar)
257 proxyCode <<
" v.push_back(a" << ivar <<
");\n";
261 proxyCode <<
" return TPyReturn(TPyArg::CallMethod((PyObject*)" << std::showbase << (uintptr_t)attr <<
", v))";
263 proxyCode <<
" TPyArg::CallConstructor(fPyObject, (PyObject*)" << std::showbase << (uintptr_t)pyclass <<
", v)";
264 proxyCode <<
";\n }\n";
273 proxyCode <<
" " << clName <<
"() {\n TPyArg::CallConstructor(fPyObject, (PyObject*)" << std::showbase << (uintptr_t)pyclass
277 proxyCode <<
" ~" << clName <<
"() { TPyArg::CallDestructor(fPyObject); }\n";
280 proxyCode <<
" " << clName <<
"(const " << clName <<
"&) = delete;\n";
281 proxyCode <<
" " << clName <<
"& operator=(const " << clName <<
"&) = delete;\n";
297 TClass *klass =
new TClass(useNS ? (mdName +
"::" + clName).c_str() : clName.c_str(), silent);
308 return GetClass(typeinfo.name(), load, silent);
316 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 TObject * FindObject(const char *name) const
Must be redefined in derived classes.
virtual TClass * GetClass(const char *name, Bool_t load)
R__EXTERN PyObject * gBases
Set of helper functions that are invoked from the pythonizors, on the Python side.
R__EXTERN bool gDictLookupActive