14#include "TPyClassGenerator.h"
30 PyGILState_STATE m_GILState;
32 PyGILRAII() : m_GILState(PyGILState_Ensure()) { }
33 ~PyGILRAII() { PyGILState_Release(m_GILState); }
52 PyGILRAII thePyGILRAII;
55 PyObject *modules = PySys_GetObject(
const_cast<char *
>(
"modules"));
57 PyObject *keys = PyDict_Keys(modules);
58 Bool_t isModule = PySequence_Contains(keys, pyname);
69 std::ostringstream nsCode;
70 nsCode <<
"namespace " <<
name <<
" {\n";
73 PyObject *bases = PyUnicode_FromString(
"__bases__");
74 PyObject *mod = PyDict_GetItemString(modules,
const_cast<char *
>(
name));
75 PyObject *dct = PyModule_GetDict(mod);
76 keys = PyDict_Keys(dct);
78 for (
int i = 0; i < PyList_GET_SIZE(keys); ++i) {
79 PyObject *key = PyList_GET_ITEM(keys, i);
86 if (PyCallable_Check(
attr) && !(PyType_Check(
attr) || PyObject_HasAttr(
attr, bases))) {
87 std::string func_name = PyUnicode_AsUTF8(key);
90 PyObject *func_code = PyObject_GetAttrString(
attr, (
char *)
"func_code");
91 PyObject *var_names = func_code ? PyObject_GetAttrString(func_code, (
char *)
"co_varnames") : NULL;
92 int nVars = var_names ? PyTuple_GET_SIZE(var_names) : 0 ;
95 Py_XDECREF(var_names);
96 Py_XDECREF(func_code);
98 nsCode <<
" TPyReturn " << func_name <<
"(";
99 for (
int ivar = 0; ivar < nVars; ++ivar) {
100 nsCode <<
"const TPyArg& a" << ivar;
101 if (ivar != nVars - 1)
105 nsCode <<
" std::vector<TPyArg> v; v.reserve(" << nVars <<
");\n";
108 for (
int ivar = 0; ivar < nVars; ++ivar)
109 nsCode <<
" v.push_back(a" << ivar <<
");\n";
112 nsCode <<
" return TPyReturn(TPyArg::CallMethod((PyObject*)" << std::showbase << (uintptr_t)
attr <<
", v)); }\n";
134 std::string clName =
name;
135 std::string::size_type pos = clName.rfind(
'.');
137 if (pos == std::string::npos)
140 std::string mdName = clName.substr(0, pos);
141 clName = clName.substr(pos + 1, std::string::npos);
144 Bool_t useNS =
gROOT->GetListOfClasses()->FindObject(mdName.c_str()) != 0;
153 PyObject *mod = PyImport_AddModule(
const_cast<char *
>(mdName.c_str()));
160 PyObject *pyclass = PyDict_GetItemString(PyModule_GetDict(mod),
const_cast<char *
>(clName.c_str()));
170 PyObject *attrs = PyObject_Dir(pyclass);
178 std::ostringstream proxyCode;
180 proxyCode <<
"namespace " << mdName <<
" { ";
181 proxyCode <<
"class " << clName <<
" {\nprivate:\n PyObject* fPyObject;\npublic:\n";
185 for (
int i = 0; i < PyList_GET_SIZE(attrs); ++i) {
186 PyObject *label = PyList_GET_ITEM(attrs, i);
191 if (PyCallable_Check(
attr)) {
192 std::string mtName = PyUnicode_AsUTF8(label);
194 if (mtName ==
"__del__") {
195 hasDestructor =
kTRUE;
196 proxyCode <<
" ~" << clName <<
"() { TPyArg::CallDestructor(fPyObject); }\n";
200 Bool_t isConstructor = mtName ==
"__init__";
201 if (!isConstructor && mtName.find(
"__", 0, 2) == 0)
205#if PY_VERSION_HEX < 0x03000000
206 PyObject *im_func = PyObject_GetAttrString(
attr, (
char *)
"im_func");
207 PyObject *func_code = im_func ? PyObject_GetAttrString(im_func, (
char *)
"func_code") : NULL;
209 PyObject *func_code = PyObject_GetAttrString(
attr,
"__code__");
211 PyObject *var_names = func_code ? PyObject_GetAttrString(func_code, (
char *)
"co_varnames") : NULL;
212 if (PyErr_Occurred())
216 var_names ? PyTuple_GET_SIZE(var_names) - 1 : 0 ;
219 Py_XDECREF(var_names);
220 Py_XDECREF(func_code);
221#if PY_VERSION_HEX < 0x03000000
227 hasConstructor =
kTRUE;
228 proxyCode <<
" " << clName <<
"(";
230 proxyCode <<
" TPyReturn " << mtName <<
"(";
231 for (
int ivar = 0; ivar < nVars; ++ivar) {
232 proxyCode <<
"const TPyArg& a" << ivar;
233 if (ivar != nVars - 1)
236 proxyCode <<
") {\n";
237 proxyCode <<
" std::vector<TPyArg> v; v.reserve(" << nVars + (isConstructor ? 0 : 1) <<
");\n";
241 proxyCode <<
" v.push_back(fPyObject);\n";
244 for (
int ivar = 0; ivar < nVars; ++ivar)
245 proxyCode <<
" v.push_back(a" << ivar <<
");\n";
249 proxyCode <<
" return TPyReturn(TPyArg::CallMethod((PyObject*)" << std::showbase << (uintptr_t)
attr <<
", v))";
251 proxyCode <<
" TPyArg::CallConstructor(fPyObject, (PyObject*)" << std::showbase << (uintptr_t)pyclass <<
", v)";
252 proxyCode <<
";\n }\n";
261 proxyCode <<
" " << clName <<
"() {\n TPyArg::CallConstructor(fPyObject, (PyObject*)" << std::showbase << (uintptr_t)pyclass
265 proxyCode <<
" ~" << clName <<
"() { TPyArg::CallDestructor(fPyObject); }\n";
268 proxyCode <<
" " << clName <<
"(const " << clName <<
"&) = delete;\n";
269 proxyCode <<
" " << clName <<
"& operator=(const " << clName <<
"&) = delete;\n";
285 TClass *klass =
new TClass(useNS ? (mdName +
"::" + clName).c_str() : clName.c_str(), silent);
296 return GetClass(typeinfo.name(), load, silent);
304 return GetClass(typeinfo.name(), load);
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t attr
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.
TClass * GetClass(const char *name, Bool_t load) override