27 PyGILState_STATE m_GILState;
29 PyGILRAII() : m_GILState(PyGILState_Ensure()) {}
30 ~PyGILRAII() { PyGILState_Release(m_GILState); }
52 if ( ! load || !
name )
55 PyGILRAII thePyGILRAII;
58 PyObject* modules = PySys_GetObject(
const_cast<char*
>(
"modules") );
60 PyObject* keys = PyDict_Keys( modules );
61 bool isModule = PySequence_Contains( keys,
pyname );
71 std::ostringstream nsCode;
72 nsCode <<
"namespace " <<
name <<
" {\n";
75 PyObject* mod = PyDict_GetItemString( modules,
const_cast<char*
>(
name) );
76 PyObject* dct = PyModule_GetDict( mod );
77 keys = PyDict_Keys( dct );
79 for (
int i = 0; i < PyList_GET_SIZE( keys ); ++i ) {
80 PyObject* key = PyList_GET_ITEM( keys, i );
83 PyObject* attr = PyDict_GetItem( dct, key );
87 if ( PyCallable_Check( attr ) && \
89 std::string func_name = PyROOT_PyUnicode_AsString( key );
92 PyObject* func_code = PyObject_GetAttrString( attr, (
char*)
"func_code" );
94 func_code ? PyObject_GetAttrString( func_code, (
char*)
"co_varnames" ) : NULL;
95 int nVars = var_names ? PyTuple_GET_SIZE( var_names ) : 0 ;
96 if ( nVars < 0 ) nVars = 0;
97 Py_XDECREF( var_names );
98 Py_XDECREF( func_code );
100 nsCode <<
" TPyReturn " << func_name <<
"(";
101 for (
int ivar = 0; ivar < nVars; ++ivar ) {
102 nsCode <<
"const TPyArg& a" << ivar;
103 if ( ivar != nVars-1 ) nsCode <<
", ";
106 nsCode <<
" std::vector<TPyArg> v; v.reserve(" << nVars <<
");\n";
109 for (
int ivar = 0; ivar < nVars; ++ ivar )
110 nsCode <<
" v.push_back(a" << ivar <<
");\n";
113 nsCode <<
" return TPyReturn(TPyArg::CallMethod((PyObject*)" << (
void*)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 useNS =
gROOT->GetListOfClasses()->FindObject( mdName.c_str() ) != 0;
152 PyObject* mod = PyImport_AddModule(
const_cast< char*
>( mdName.c_str() ) );
160 PyDict_GetItemString( PyModule_GetDict( mod ),
const_cast< char*
>( clName.c_str() ) );
161 Py_XINCREF( pyclass );
170 PyObject* attrs = PyObject_Dir( pyclass );
173 Py_DECREF( pyclass );
178 std::ostringstream proxyCode;
179 if ( useNS ) proxyCode <<
"namespace " << mdName <<
" { ";
180 proxyCode <<
"class " << clName <<
" {\nprivate:\n PyObject* fPyObject;\npublic:\n";
183 bool hasConstructor =
false, hasDestructor =
false;
184 for (
int i = 0; i < PyList_GET_SIZE( attrs ); ++i ) {
185 PyObject* label = PyList_GET_ITEM( attrs, i );
187 PyObject* attr = PyObject_GetAttr( pyclass, label );
190 if ( PyCallable_Check( attr ) ) {
191 std::string mtName = PyROOT_PyUnicode_AsString( label );
193 if ( mtName ==
"__del__" ) {
194 hasDestructor =
true;
195 proxyCode <<
" ~" << clName <<
"() { TPyArg::CallDestructor(fPyObject); }\n";
199 bool isConstructor = mtName ==
"__init__";
200 if ( !isConstructor && mtName.find(
"__", 0, 2) == 0 )
204#if PY_VERSION_HEX < 0x03000000
205 PyObject* im_func = PyObject_GetAttrString( attr, (
char*)
"im_func" );
207 im_func ? PyObject_GetAttrString( im_func, (
char*)
"func_code" ) : NULL;
209 PyObject* func_code = PyObject_GetAttrString( attr,
"__code__" );
212 func_code ? PyObject_GetAttrString( func_code, (
char*)
"co_varnames" ) : NULL;
213 if (PyErr_Occurred()) PyErr_Clear();
215 int nVars = var_names ? PyTuple_GET_SIZE( var_names ) - 1 : 0 ;
216 if ( nVars < 0 ) nVars = 0;
217 Py_XDECREF( var_names );
218 Py_XDECREF( func_code );
219#if PY_VERSION_HEX < 0x03000000
220 Py_XDECREF( im_func );
224 if ( isConstructor ) {
225 hasConstructor =
true;
226 proxyCode <<
" " << clName <<
"(";
228 proxyCode <<
" TPyReturn " << mtName <<
"(";
229 for (
int ivar = 0; ivar < nVars; ++ivar ) {
230 proxyCode <<
"const TPyArg& a" << ivar;
231 if ( ivar != nVars-1 ) proxyCode <<
", ";
233 proxyCode <<
") {\n";
234 proxyCode <<
" std::vector<TPyArg> v; v.reserve(" << nVars+(isConstructor ? 0 : 1) <<
");\n";
237 if ( ! isConstructor )
238 proxyCode <<
" v.push_back(fPyObject);\n";
241 for (
int ivar = 0; ivar < nVars; ++ ivar )
242 proxyCode <<
" v.push_back(a" << ivar <<
");\n";
245 if ( ! isConstructor )
246 proxyCode <<
" return TPyReturn(TPyArg::CallMethod((PyObject*)" << (
void*)attr <<
", v))";
248 proxyCode <<
" TPyArg::CallConstructor(fPyObject, (PyObject*)" << (
void*)pyclass <<
", v)";
249 proxyCode <<
";\n }\n";
257 if ( ! hasConstructor )
258 proxyCode <<
" " << clName <<
"() {\n TPyArg::CallConstructor(fPyObject, (PyObject*)" << (
void*)pyclass <<
"); }\n";
260 if ( ! hasDestructor )
261 proxyCode <<
" ~" << clName <<
"() { TPyArg::CallDestructor(fPyObject); }\n";
264 proxyCode <<
" " << clName <<
"(const " << clName <<
"&) = delete;\n";
265 proxyCode <<
" " << clName <<
"& operator=(const " << clName <<
"&) = delete;\n";
269 if ( useNS ) proxyCode <<
" }";
273 Py_DECREF( pyclass );
276 if ( !
gInterpreter->LoadText( proxyCode.str().c_str() ) )
280 TClass* klass =
new TClass( useNS ? (mdName+
"::"+clName).c_str() : clName.c_str(), silent );
291 return GetClass( typeinfo.name(), load, silent );
299 return GetClass( typeinfo.name(), load );
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)