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#if PY_VERSION_HEX < 0x30d00f0
91 PyObject *func_code = PyObject_GetAttrString(
attr, (
char *)
"func_code");
94 PyObject_GetOptionalAttrString(
attr, (
char *)
"func_code", &func_code);
96 PyObject *var_names = func_code ? PyObject_GetAttrString(func_code, (
char *)
"co_varnames") : NULL;
97 int nVars = var_names ? PyTuple_GET_SIZE(var_names) : 0 ;
100 Py_XDECREF(var_names);
101 Py_XDECREF(func_code);
103 nsCode <<
" TPyReturn " << func_name <<
"(";
104 for (
int ivar = 0; ivar < nVars; ++ivar) {
105 nsCode <<
"const TPyArg& a" << ivar;
106 if (ivar != nVars - 1)
110 nsCode <<
" std::vector<TPyArg> v; v.reserve(" << nVars <<
");\n";
113 for (
int ivar = 0; ivar < nVars; ++ivar)
114 nsCode <<
" v.push_back(a" << ivar <<
");\n";
117 nsCode <<
" return TPyReturn(TPyArg::CallMethod((PyObject*)" << std::showbase << (uintptr_t)
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);
196 if (PyCallable_Check(
attr)) {
197 std::string mtName = PyUnicode_AsUTF8(label);
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*)" << std::showbase << (uintptr_t)
attr <<
", v))";
256 proxyCode <<
" TPyArg::CallConstructor(fPyObject, (PyObject*)" << std::showbase << (uintptr_t)pyclass <<
", v)";
257 proxyCode <<
";\n }\n";
266 proxyCode <<
" " << clName <<
"() {\n TPyArg::CallConstructor(fPyObject, (PyObject*)" << std::showbase << (uintptr_t)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);
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