28 PyObject* meta_alloc( PyTypeObject* metatype, Py_ssize_t nitems )
31 PyObject* pyclass = PyType_Type.tp_alloc( metatype, nitems );
38 void meta_dealloc( PyRootClass* pytype )
40 return PyType_Type.tp_dealloc( (PyObject*)pytype );
48 PyObject* pt_new( PyTypeObject* subtype, PyObject* args, PyObject* kwds )
52 subtype->tp_alloc = (allocfunc)meta_alloc;
53 subtype->tp_dealloc = (destructor)meta_dealloc;
56 PyRootClass* result = (PyRootClass*)PyType_Type.tp_new( subtype, args, kwds );
64 const char* mp = strstr( subtype->tp_name,
"_meta" );
68 result->fCppType = Cppyy::GetScope(
69 PyROOT_PyUnicode_AsString( PyTuple_GET_ITEM( args, 0 ) ) );
73 result->fCppType = Cppyy::GetScope(
74 std::string( subtype->tp_name ).substr( 0, mp-subtype->tp_name ).c_str() );
77 return (PyObject*)result;
82 PyObject* pt_getattro( PyObject* pyclass, PyObject* pyname )
85 PyObject* attr = PyType_Type.tp_getattro( pyclass, pyname );
88 if ( ! attr && PyROOT_PyUnicode_CheckExact( pyname ) ) {
89 PyObject *etype, *value, *trace;
90 PyErr_Fetch( &etype, &value, &trace );
93 std::string name = PyROOT_PyUnicode_AsString( pyname );
95 if ( name.size() <= 2 || name.substr( 0, 2 ) !=
"__" ) {
96 attr = CreateScopeProxy( name, pyclass );
100 if ( ! attr && ! PyRootType_CheckExact( pyclass ) && PyType_Check( pyclass ) ) {
102 PyObject* pycppname = PyObject_GetAttr( pyclass, PyStrings::gCppName );
103 const char* cppname = PyROOT_PyUnicode_AsString(pycppname);
104 Py_DECREF(pycppname);
105 Cppyy::TCppScope_t scope = Cppyy::GetScope( cppname );
106 TClass* klass = TClass::GetClass( cppname );
107 if ( Cppyy::IsNamespace( scope ) ) {
110 TObject *methObj =
nullptr;
111 if ( (methObj = klass->GetListOfMethods()->FindObject(name.c_str())) ) {
113 auto completeName = methObj->GetName();
114 std::vector< PyCallable* > overloads;
115 const size_t nmeth = Cppyy::GetNumMethods( scope );
116 for (
size_t imeth = 0; imeth < nmeth; ++imeth ) {
117 Cppyy::TCppMethod_t method = Cppyy::GetMethod( scope, imeth );
118 auto currentName = Cppyy::GetMethodName(method);
124 if (currentName == completeName)
125 overloads.push_back(
new TFunctionHolder( scope, method ) );
131 attr = (PyObject*)MethodProxy_New( name.c_str(), overloads );
137 Cppyy::TCppIndex_t dmi = Cppyy::GetDatamemberIndex( scope, name );
138 if ( 0 <= dmi ) attr = (PyObject*)PropertyProxy_New( scope, dmi );
143 if ( ! attr && klass ) {
144 TFunctionTemplate* tmpl = klass->GetFunctionTemplate( name.c_str() );
146 attr = (PyObject*)TemplateProxy_New( name, pyclass );
151 if (Cppyy::IsEnum(Cppyy::GetScopedFinalName(scope)+
"::"+name)) {
153 Cppyy::TCppEnum_t enumtype = Cppyy::GetEnum(scope, name);
156 Cppyy::TCppIndex_t ndata = Cppyy::GetNumEnumData(enumtype);
157 PyObject* dct = PyDict_New();
158 for (Cppyy::TCppIndex_t idata = 0; idata < ndata; ++idata) {
159 PyObject* val = PyLong_FromLongLong(Cppyy::GetEnumDataValue(enumtype, idata));
160 PyDict_SetItemString(dct, Cppyy::GetEnumDataName(enumtype, idata).c_str(), val);
165 PyObject* cppnamepy = PyROOT_PyUnicode_FromString((Cppyy::GetScopedFinalName(scope)+
"::"+name).c_str());
166 PyDict_SetItem(dct, PyStrings::gCppName, cppnamepy);
168 PyDict_SetItem(dct, PyStrings::gCppNameNew, cppnamepy);
169 Py_DECREF(cppnamepy);
172 PyObject* pybases = PyTuple_New(1);
173 Py_INCREF(&PyInt_Type);
174 PyTuple_SET_ITEM(pybases, 0, (PyObject*)&PyInt_Type);
175 PyObject* args = Py_BuildValue((
char*)
"sOO", name.c_str(), pybases, dct);
176 attr = Py_TYPE(&PyInt_Type)->tp_new(Py_TYPE(&PyInt_Type), args,
nullptr);
182 Py_INCREF(&PyInt_Type);
183 attr = (PyObject*)&PyInt_Type;
189 PyObject_SetAttr( pyclass, pyname, attr );
191 attr = PyType_Type.tp_getattro( pyclass, pyname );
195 if ( ! attr && ! PyRootType_Check( pyclass ) ) {
198 attr = GetCppGlobal( name );
199 if ( PropertyProxy_Check( attr ) ) {
200 PyObject_SetAttr( (PyObject*)Py_TYPE(pyclass), pyname, attr );
202 attr = PyType_Type.tp_getattro( pyclass, pyname );
204 PyObject_SetAttr( pyclass, pyname, attr );
210 if ( ! attr && etype )
211 PyErr_Restore( etype, value, trace );
213 PyObject* sklass = PyObject_Str( pyclass );
214 PyErr_Format( PyExc_AttributeError,
"%s has no attribute \'%s\'",
215 PyROOT_PyUnicode_AsString( sklass ), PyROOT_PyUnicode_AsString( pyname ) );
229 PyTypeObject PyRootType_Type = {
230 PyVarObject_HEAD_INIT( &PyType_Type, 0 )
231 (
char*)
"ROOT.PyRootType",
232 sizeof(PyROOT::PyRootClass),
246 (getattrofunc)pt_getattro,
249 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
250 (
char*)
"PyROOT metatype (internal)",
275 #
if PY_VERSION_HEX >= 0x02030000
278 #
if PY_VERSION_HEX >= 0x02060000
281 #
if PY_VERSION_HEX >= 0x03040000