50 R__EXTERN PyObject* gRootModule;
53 R__EXTERN std::vector<std::pair<Cppyy::TCppType_t, Cppyy::TCppType_t> > gPinnedTypes;
54 R__EXTERN std::vector<Cppyy::TCppType_t> gIgnorePinnings;
60 typedef std::map< Cppyy::TCppScope_t, PyObject* > PyClassMap_t;
61 PyClassMap_t gPyClasses;
64 PyObject* CreateNewROOTPythonClass(
const std::string& name, PyObject* pybases )
67 Py_XINCREF( pybases );
69 pybases = PyTuple_New( 1 );
70 Py_INCREF( (PyObject*)(
void*)&PyROOT::ObjectProxy_Type );
71 PyTuple_SET_ITEM( pybases, 0, (PyObject*)(
void*)&PyROOT::ObjectProxy_Type );
74 PyObject* pymetabases = PyTuple_New( PyTuple_GET_SIZE( pybases ) );
75 for (
int i = 0; i < PyTuple_GET_SIZE( pybases ); ++i ) {
76 PyObject* btype = (PyObject*)Py_TYPE( PyTuple_GetItem( pybases, i ) );
78 PyTuple_SET_ITEM( pymetabases, i, btype );
81 PyObject* args = Py_BuildValue( (
char*)
"sO{}", (name+
"_meta").c_str(), pymetabases );
82 Py_DECREF( pymetabases );
84 PyObject* pymeta = PyType_Type.tp_new( &PyROOT::PyRootType_Type, args, NULL );
92 args = Py_BuildValue( (
char*)
"sO{}", Cppyy::GetName(name).c_str(), pybases );
93 PyObject* pyclass = ((PyTypeObject*)pymeta)->tp_new( (PyTypeObject*)pymeta, args, NULL );
102 inline void AddPropertyToClass1(
103 PyObject* pyclass, PyROOT::PropertyProxy* property, Bool_t isStatic )
106 PyObject_SetAttrString( pyclass,
107 const_cast< char* >( property->GetName().c_str() ), (PyObject*)property );
111 PyObject_SetAttrString( (PyObject*)Py_TYPE(pyclass),
112 const_cast< char* >( property->GetName().c_str() ), (PyObject*)property );
116 void AddPropertyToClass( PyObject* pyclass,
117 Cppyy::TCppScope_t scope, Cppyy::TCppIndex_t idata )
119 PyROOT::PropertyProxy*
property = PyROOT::PropertyProxy_New( scope, idata );
120 AddPropertyToClass1( pyclass, property, Cppyy::IsStaticData( scope, idata ) );
121 Py_DECREF( property );
124 void AddConstantPropertyToClass( PyObject* pyclass,
125 Cppyy::TCppScope_t scope,
const std::string& name,
void* address, TEnum* en )
127 PyROOT::PropertyProxy*
property =
128 PyROOT::PropertyProxy_NewConstant( scope, name, address, en );
129 AddPropertyToClass1( pyclass, property, kTRUE );
130 Py_DECREF( property );
140 using namespace PyROOT;
142 inline void AddToGlobalScope(
143 const char* label,
const char* , TObject* obj, Cppyy::TCppType_t klass )
147 PyModule_AddObject( gRootModule, const_cast< char* >( label ),
148 PyROOT::BindCppObjectNoCast( obj, klass ) );
151 std::set< std::string > gSTLTypes, gSTLExceptions;
152 struct InitSTLTypes_t {
156 const std::string nss =
"std::";
158 const char* stlTypes[] = {
"complex",
"exception",
159 "deque",
"list",
"queue",
"stack",
"vector",
160 "map",
"multimap",
"set",
"multiset" };
161 for (
int i = 0; i < int(
sizeof(stlTypes)/
sizeof(stlTypes[0])); ++i ) {
162 gSTLTypes.insert( stlTypes[ i ] );
163 gSTLTypes.insert( nss + stlTypes[ i ] );
166 const char* stlExceptions[] = {
"logic_error",
"domain_error",
167 "invalid_argument",
"length_error",
"out_of_range",
"runtime_error",
168 "range_error",
"overflow_error",
"underflow_error" };
169 for (
int i = 0; i < int(
sizeof(stlExceptions)/
sizeof(stlExceptions[0])); ++i ) {
170 gSTLExceptions.insert( stlExceptions[ i ] );
171 gSTLExceptions.insert( nss + stlExceptions[ i ] );
178 static TMemoryRegulator &GetMemoryRegulator() {
179 static TMemoryRegulator m;
184 void PyROOT::InitRoot()
187 PyEval_InitThreads();
190 gROOT->GetListOfCleanups()->Add( &GetMemoryRegulator() );
193 AddToGlobalScope(
"gROOT",
"TROOT.h", gROOT, Cppyy::GetScope( gROOT->IsA()->GetName() ) );
194 AddToGlobalScope(
"gSystem",
"TSystem.h", gSystem, Cppyy::GetScope( gSystem->IsA()->GetName() ) );
195 AddToGlobalScope(
"gInterpreter",
"TInterpreter.h", gInterpreter, Cppyy::GetScope( gInterpreter->IsA()->GetName() ) );
202 static int BuildScopeProxyDict( Cppyy::TCppScope_t scope, PyObject* pyclass ) {
204 Bool_t isNamespace = Cppyy::IsNamespace( scope );
205 Bool_t hasConstructor = kFALSE;
208 typedef std::vector< PyCallable* > Callables_t;
209 typedef std::map< std::string, Callables_t > CallableCache_t;
210 CallableCache_t cache;
213 getattrofunc oldgetattro = Py_TYPE(pyclass)->tp_getattro;
214 Py_TYPE(pyclass)->tp_getattro = PyType_Type.tp_getattro;
217 auto cppClass = TClass::GetClass(Cppyy::GetFinalName(scope).c_str());
218 for (
auto templ : ROOT::Detail::TRangeStaticCast<TFunctionTemplate>(cppClass->GetListOfFunctionTemplates())) {
219 if (templ->Property() & kIsPublic) {
220 auto templName = templ->GetName();
221 auto attr = PyObject_GetAttrString(pyclass, templName);
222 if (!TemplateProxy_Check(attr)) {
223 auto templProxy = TemplateProxy_New(templName, pyclass);
224 PyObject_SetAttrString(pyclass, templName, (PyObject*)templProxy);
225 Py_DECREF(templProxy);
233 const Cppyy::TCppIndex_t nMethods =
234 Cppyy::IsNamespace( scope ) ? 0 : Cppyy::GetNumMethods( scope );
235 for ( Cppyy::TCppIndex_t imeth = 0; imeth < nMethods; ++imeth ) {
236 Cppyy::TCppMethod_t method = Cppyy::GetMethod( scope, imeth );
239 std::string mtName = Cppyy::GetMethodName( method );
242 Bool_t setupSetItem = kFALSE;
243 Bool_t isConstructor = Cppyy::IsConstructor( method );
250 if ( mtName[0] ==
'~' )
254 mtName = Utility::MapOperatorName( mtName, Cppyy::GetMethodNumArgs( method ) );
257 if ( mtName ==
"__call__" || mtName ==
"__getitem__" ) {
258 const std::string& qual_return = Cppyy::ResolveName( Cppyy::GetMethodResultType( method ) );
259 if ( qual_return.find(
"const", 0, 5 ) == std::string::npos ) {
260 const std::string& cpd = Utility::Compound( qual_return );
261 if ( ! cpd.empty() && cpd[ cpd.size() - 1 ] ==
'&' ) {
262 setupSetItem = kTRUE;
268 Bool_t isStatic = Cppyy::IsStaticMethod( method );
271 std::string tmplName =
"";
272 if ( ! (isNamespace || isStatic || isConstructor) && mtName[mtName.size()-1] ==
'>' ) {
273 tmplName = mtName.substr( 0, mtName.find(
'<') );
276 PyObject* attr = PyObject_GetAttrString( pyclass, const_cast< char* >( tmplName.c_str() ) );
277 if ( ! TemplateProxy_Check( attr ) ) {
279 TemplateProxy* pytmpl = TemplateProxy_New( tmplName, pyclass );
280 if ( MethodProxy_Check( attr ) ) pytmpl->AddOverload( (MethodProxy*)attr );
281 PyObject_SetAttrString(
282 pyclass, const_cast< char* >( tmplName.c_str() ), (PyObject*)pytmpl );
293 if ( ! Cppyy::IsPublicMethod( method ) ) {
297 const std::string& clName = TClassEdit::ShortType(
298 Cppyy::GetFinalName( scope ).c_str(), TClassEdit::kDropAlloc );
299 mtName =
"_" + clName +
"__" + mtName;
304 PyCallable* pycall = 0;
306 pycall =
new TClassMethodHolder( scope, method );
307 else if ( isNamespace )
308 pycall =
new TFunctionHolder( scope, method );
309 else if ( isConstructor ) {
310 pycall =
new TConstructorHolder( scope, method );
312 hasConstructor = kTRUE;
314 pycall =
new TMethodHolder( scope, method );
317 Callables_t& md = (*(cache.insert(
318 std::make_pair( mtName, Callables_t() ) ).first)).second;
319 md.push_back( pycall );
322 if ( setupSetItem ) {
323 Callables_t& setitem = (*(cache.insert(
324 std::make_pair( std::string(
"__setitem__" ), Callables_t() ) ).first)).second;
325 setitem.push_back(
new TSetItemHolder( scope, method ) );
329 if ( ! tmplName.empty() ) {
330 PyObject* attr = PyObject_GetAttrString( pyclass, const_cast< char* >( tmplName.c_str() ) );
331 ((TemplateProxy*)attr)->AddTemplate( pycall->Clone() );
337 if ( ! isNamespace && ! hasConstructor )
338 cache[
"__init__" ].push_back(
new TConstructorHolder( scope, (Cppyy::TCppMethod_t)0 ) );
341 for ( CallableCache_t::iterator imd = cache.begin(); imd != cache.end(); ++imd ) {
345 PyObject* attr = PyObject_GetAttrString( pyclass, const_cast< char* >( imd->first.c_str() ) );
346 if ( TemplateProxy_Check( attr ) ) {
348 for ( Callables_t::iterator cit = imd->second.begin(); cit != imd->second.end(); ++cit )
349 ((TemplateProxy*)attr)->AddOverload( *cit );
351 if ( ! attr ) PyErr_Clear();
353 MethodProxy* method = MethodProxy_New( imd->first, imd->second );
354 PyObject_SetAttrString(
355 pyclass, const_cast< char* >( method->GetName().c_str() ), (PyObject*)method );
363 TClass* klass = TClass::GetClass( Cppyy::GetFinalName( scope ).c_str() );
364 TList* enums = klass->GetListOfEnums();
365 TIter ienum( enums );
367 while ( (e = (TEnum*)ienum.Next()) ) {
368 const TSeqCollection* seq = e->GetConstants();
369 auto isScoped = e->Property() & kIsScopedEnum;
370 if (isScoped)
continue;
371 for ( Int_t i = 0; i < seq->GetSize(); i++ ) {
372 TEnumConstant* ec = (TEnumConstant*)seq->At( i );
373 AddConstantPropertyToClass( pyclass, scope, ec->GetName(), ec->GetAddress(), e );
378 const Cppyy::TCppIndex_t nDataMembers = Cppyy::GetNumDatamembers( scope );
379 for ( Cppyy::TCppIndex_t idata = 0; idata < nDataMembers; ++idata ) {
381 if ( ! Cppyy::IsPublicData( scope, idata ) )
385 if ( Cppyy::IsEnumData( scope, idata ) && Cppyy::IsStaticData( scope, idata ) ) {
387 if ( ! Cppyy::GetDatamemberOffset( scope, idata ) )
392 PyObject* eset = PyObject_GetAttrString( pyclass,
393 const_cast<char*>( Cppyy::GetDatamemberName( scope, idata ).c_str()) );
403 if ( strstr( Cppyy::GetDatamemberType( scope, idata ).c_str(),
"(anonymous)" ) != 0 ) {
404 AddPropertyToClass( pyclass, scope, idata );
410 AddPropertyToClass( pyclass, scope, idata );
414 Py_TYPE(pyclass)->tp_getattro = oldgetattro;
423 static PyObject* BuildCppClassBases( Cppyy::TCppType_t klass )
425 size_t nbases = Cppyy::GetNumBases( klass );
428 std::vector< std::string > uqb;
429 uqb.reserve( nbases );
431 for (
size_t ibase = 0; ibase < nbases; ++ibase ) {
432 const std::string& name = Cppyy::GetBaseName( klass, ibase );
433 if ( std::find( uqb.begin(), uqb.end(), name ) == uqb.end() ) {
434 uqb.push_back( name );
441 PyObject* pybases = PyTuple_New( nbases ? nbases : 1 );
447 Py_INCREF( (PyObject*)(
void*)&ObjectProxy_Type );
448 PyTuple_SET_ITEM( pybases, 0, (PyObject*)(
void*)&ObjectProxy_Type );
450 for ( std::vector< std::string >::size_type ibase = 0; ibase < nbases; ++ibase ) {
451 PyObject* pyclass = CreateScopeProxy( uqb[ ibase ] );
453 Py_DECREF( pybases );
457 PyTuple_SET_ITEM( pybases, ibase, pyclass );
462 if ( ! PyObject_IsSubclass( PyTuple_GET_ITEM( pybases, 0 ), (PyObject*)&ObjectProxy_Type ) ) {
463 PyObject* newpybases = PyTuple_New( nbases + 1 );
464 Py_INCREF( (PyObject*)(
void*)&ObjectProxy_Type );
465 PyTuple_SET_ITEM( newpybases, 0, (PyObject*)(
void*)&ObjectProxy_Type );
466 for (
int ibase = 0; ibase < (int)nbases; ++ibase ) {
467 PyObject* pyclass = PyTuple_GET_ITEM( pybases, ibase );
468 Py_INCREF( pyclass );
469 PyTuple_SET_ITEM( newpybases, ibase + 1, pyclass );
471 Py_DECREF( pybases );
472 pybases = newpybases;
482 PyObject* PyROOT::GetScopeProxy( Cppyy::TCppScope_t scope )
484 PyClassMap_t::iterator pci = gPyClasses.find( scope );
485 if ( pci != gPyClasses.end() ) {
486 PyObject* pyclass = PyWeakref_GetObject( pci->second );
488 Py_INCREF( pyclass );
499 PyObject* PyROOT::CreateScopeProxy( Cppyy::TCppScope_t scope )
501 PyObject* pyclass = GetScopeProxy( scope );
505 return CreateScopeProxy( Cppyy::GetScopedFinalName( scope ) );
511 PyObject* PyROOT::CreateScopeProxy( PyObject*, PyObject* args )
513 std::string cname = PyROOT_PyUnicode_AsString( PyTuple_GetItem( args, 0 ) );
514 if ( PyErr_Occurred() )
517 return CreateScopeProxy( cname );
523 PyObject* PyROOT::CreateScopeProxy(
const std::string& scope_name, PyObject* parent )
525 if ( scope_name.empty() || scope_name ==
"std" ) {
527 PyObject* mods = PyImport_GetModuleDict();
528 PyObject* gbl = PyDict_GetItemString( mods,
"cppyy.gbl" );
530 if ( scope_name.empty() ) {
534 return PyObject_GetAttrString( gbl,
"std" );
536 PyErr_SetString( PyExc_SystemError,
"could not locate global namespace" );
541 Bool_t force = parent != 0;
544 std::string name = scope_name;
547 std::string scName =
"";
549 PyObject* pyparent = PyObject_GetAttr( parent, PyStrings::gCppName );
552 pyparent = PyObject_GetAttr( parent, PyStrings::gName );
555 PyErr_Format( PyExc_SystemError,
"given scope has no name for %s", name.c_str() );
560 scName = PyROOT_PyUnicode_AsString( pyparent );
561 Py_DECREF( pyparent );
562 if ( PyErr_Occurred() )
570 const std::string& lookup = parent ? (scName+
"::"+name) : name;
571 Cppyy::TCppScope_t klass = Cppyy::GetScope( lookup );
573 if ( ! (Bool_t)klass && gInterpreter->CheckClassTemplate( lookup.c_str() ) ) {
575 PyObject* pytcl = PyObject_GetAttr( gRootModule, PyStrings::gTemplate );
576 PyObject* pytemplate = PyObject_CallFunction(
577 pytcl, const_cast< char* >(
"s" ), const_cast< char* >( lookup.c_str() ) );
581 PyObject_SetAttrString( parent ? parent : gRootModule, (
char*)name.c_str(), pytemplate );
584 Py_XDECREF( parent );
588 if ( ! (Bool_t)klass ) {
589 if ( ! parent && scope_name.find(
"ROOT::" ) == std::string::npos ) {
591 klass = Cppyy::GetScope(
"ROOT::"+scope_name );
592 if ( (Bool_t)klass ) {
593 PyObject* rtns = PyObject_GetAttr( gRootModule, PyStrings::gROOTns );
594 PyObject* pyclass = CreateScopeProxy( scope_name, rtns );
600 PyErr_Format( PyExc_TypeError,
"requested class \'%s\' does not exist", lookup.c_str() );
601 Py_XDECREF( parent );
606 PyObject* pyscope = GetScopeProxy( klass );
608 if ( parent ) PyObject_SetAttrString( parent, (
char*)scope_name.c_str(), pyscope );
613 std::string::size_type last = 0;
617 for ( std::string::size_type pos = 0; pos < name.size(); ++pos ) {
618 std::string::value_type c = name[ pos ];
627 else if ( tpl_open == 0 &&\
628 c ==
':' && pos+1 < name.size() && name[ pos+1 ] ==
':' ) {
630 const std::string& part = name.substr( last, pos-last );
632 PyObject* next = PyObject_GetAttrString(
633 parent ? parent : gRootModule, const_cast< char* >( part.c_str() ) );
637 next = CreateScopeProxy( part, parent );
639 Py_XDECREF( parent );
653 if ( parent && !PyRootType_Check( parent ) ) {
656 std::string unscoped = scope_name.substr( last, std::string::npos );
657 return PyObject_GetAttrString( parent, unscoped.c_str() );
663 parent = gRootModule;
668 const std::string& actual = Cppyy::GetFinalName( klass );
671 PyObject* pyactual = PyROOT_PyUnicode_FromString( Cppyy::GetName(actual).c_str() );
672 PyObject* pyclass = force ? 0 : PyObject_GetAttr( parent, pyactual );
674 Bool_t bClassFound = pyclass ? kTRUE : kFALSE;
682 PyObject* pybases = BuildCppClassBases( klass );
683 if ( pybases != 0 ) {
685 pyclass = CreateNewROOTPythonClass( actual, pybases );
686 Py_DECREF( pybases );
690 if ( pyclass != 0 ) {
691 if ( BuildScopeProxyDict( klass, pyclass ) != 0 ) {
693 Py_DECREF( pyclass );
696 PyObject_SetAttr( parent, pyactual, pyclass );
702 if ( pyclass && name != actual )
703 PyObject_SetAttrString( parent, const_cast< char* >( name.c_str() ), pyclass );
705 if ( pyclass && ! bClassFound ) {
707 gPyClasses[ klass ] = PyWeakref_NewRef( pyclass, NULL );
710 PyObject_SetAttrString( pyclass,
"__scope__", PyROOT_PyUnicode_FromString( scName.c_str() ) );
714 PyObject_SetAttr( pyclass, PyStrings::gCppName, PyROOT_PyUnicode_FromString( actual.c_str() ) );
716 PyObject_SetAttr( pyclass, PyStrings::gCppNameNew, PyROOT_PyUnicode_FromString( actual.c_str() ) );
720 if( parent == gRootModule) {
723 PyObject* _name_ = PyObject_GetAttr(parent, PyStrings::gName);
724 PyObject* _module_ = PyObject_GetAttr(parent, PyStrings::gModule);
726 module = PyROOT_PyUnicode_AsString(_module_);
731 module += PyROOT_PyUnicode_AsString(_name_);
735 PyObject_SetAttr( pyclass, PyStrings::gModule, PyROOT_PyUnicode_FromString( module.c_str()) );
737 Py_DECREF( pyactual );
741 if ( ! bClassFound ) {
742 if ( ! Pythonize( pyclass, actual ) ) {
743 Py_XDECREF( pyclass );
749 if ( pyclass && actual !=
"ROOT" ) {
751 std::string pyfullname = lookup;
752 std::string::size_type pos = pyfullname.find(
"::" );
753 while ( pos != std::string::npos ) {
754 pyfullname = pyfullname.replace( pos, 2,
"." );
755 pos = pyfullname.find(
"::", pos );
757 PyObject* modules = PySys_GetObject( const_cast<char*>(
"modules") );
758 if ( modules && PyDict_Check( modules) ) {
759 PyDict_SetItemString( modules,
760 const_cast<char*>((
"ROOT."+pyfullname).c_str()), pyclass );
771 PyObject* PyROOT::GetCppGlobal( PyObject*, PyObject* args )
773 std::string ename = PyROOT_PyUnicode_AsString( PyTuple_GetItem( args, 0 ) );
775 if ( PyErr_Occurred() )
778 return GetCppGlobal( ename );
784 PyObject* PyROOT::GetCppGlobal(
const std::string& name )
786 Cppyy::TCppIndex_t idata = Cppyy::GetDatamemberIndex( Cppyy::gGlobalScope, name );
788 return (PyObject*)PropertyProxy_New( Cppyy::gGlobalScope, idata );
791 const std::vector< Cppyy::TCppMethod_t >& methods =
792 Cppyy::GetMethodsFromName( Cppyy::gGlobalScope, name );
793 if ( ! methods.empty() ) {
794 std::vector< PyCallable* > overloads;
795 for (
auto method : methods )
796 overloads.push_back(
new TFunctionHolder( Cppyy::gGlobalScope, method ) );
797 return (PyObject*)MethodProxy_New( name, overloads );
801 if (Cppyy::ExistsMethodTemplate(Cppyy::gGlobalScope, name)) {
802 return (PyObject*)TemplateProxy_New(name, CreateScopeProxy(
""));
806 TDataMember* dm = TClass::GetClass(
"std" )->GetDataMember( name.c_str() );
808 Cppyy::TCppType_t klass = Cppyy::GetScope( dm->GetTrueTypeName() );
809 return BindCppObjectNoCast( (
void*)dm->GetOffset(), klass, kFALSE );
813 PyErr_Format( PyExc_LookupError,
"no such global: %s", name.c_str() );
820 PyObject *PyROOT::ClearProxiedObjects()
822 GetMemoryRegulator().ClearProxiedObjects();
829 PyObject* PyROOT::BindCppObjectNoCast(
830 Cppyy::TCppObject_t address, Cppyy::TCppType_t klass, Bool_t isRef, Bool_t isValue ) {
832 PyErr_SetString( PyExc_TypeError,
"attempt to bind ROOT object w/o class" );
837 PyObject* pyclass = CreateScopeProxy( klass );
842 PyObject* args = PyTuple_New(0);
844 (ObjectProxy*)((PyTypeObject*)pyclass)->tp_new( (PyTypeObject*)pyclass, args, NULL );
846 Py_DECREF( pyclass );
851 unsigned flags = (isRef ? ObjectProxy::kIsReference : 0) | (isValue ? ObjectProxy::kIsValue : 0);
852 pyobj->Set( address, (ObjectProxy::EFlags)flags );
856 return (PyObject*)pyobj;
862 PyObject* PyROOT::BindCppObject( Cppyy::TCppObject_t address, Cppyy::TCppType_t klass, Bool_t isRef )
865 return BindCppObjectNoCast( address, klass, kFALSE );
869 PyErr_SetString( PyExc_TypeError,
"attempt to bind ROOT object w/o class" );
876 Int_t oldval = gErrorIgnoreLevel;
877 gErrorIgnoreLevel = 5000;
878 Cppyy::TCppType_t clActual = isRef ? 0 : Cppyy::GetActualClass( klass, address );
879 gErrorIgnoreLevel = oldval;
886 static Cppyy::TCppScope_t sTObjectScope = Cppyy::GetScope(
"TObject" );
887 if ( ! isRef && Cppyy::IsSubtype( klass, sTObjectScope) ) {
888 object = (TObject*)((Long_t)address + \
889 Cppyy::GetBaseOffset( klass, sTObjectScope, address, 1 ) );
892 PyObject* oldPyObject = TMemoryRegulator::RetrieveObject(
object, clActual ? clActual : klass );
898 if ( clActual && klass != clActual ) {
899 ptrdiff_t offset = Cppyy::GetBaseOffset(
900 clActual, klass, address, -1 ,
true );
901 if ( offset != -1 ) {
902 address = (
void*)((Long_t)address + offset);
909 Bool_t ignore_pin = std::find(
910 gIgnorePinnings.begin(), gIgnorePinnings.end(), klass ) != gIgnorePinnings.end();
912 if ( ! ignore_pin ) {
913 for (
auto it = gPinnedTypes.cbegin(); it != gPinnedTypes.cend(); ++it ) {
914 if ( klass == std::get<0>(*it) || Cppyy::IsSubtype( klass, std::get<0>(*it) ) )
915 klass = std::get<1>(*it);
920 ObjectProxy* pyobj = (ObjectProxy*)BindCppObjectNoCast( address, klass, isRef );
925 if (
object && !(pyobj->fFlags & ObjectProxy::kIsReference) ) {
926 TMemoryRegulator::RegisterObject( pyobj,
object );
930 return (PyObject*)pyobj;
936 PyObject* PyROOT::BindCppObjectArray(
937 Cppyy::TCppObject_t address, Cppyy::TCppType_t klass, Int_t size ) {
938 return TTupleOfInstances_New( address, klass, size );
945 PyObject* PyROOT::BindCppGlobal( TGlobal* gbl )
947 if ( ! gbl || strcmp(gbl->GetName(),
"") == 0 ) {
948 Py_INCREF( Py_None );
953 Cppyy::TCppType_t klass = Cppyy::GetScope( gbl->GetTypeName() );
956 if ( gbl->GetArrayDim() == 1 ) {
957 return BindCppObjectArray( (
void*)gbl->GetAddress(), klass, gbl->GetMaxIndex(0) );
958 }
else if ( gbl->GetArrayDim() ) {
959 PyErr_SetString( PyExc_NotImplementedError,
960 "larger than 1D arrays of objects not supported" );
970 if ( Utility::Compound( gbl->GetFullTypeName() ) !=
"" )
971 return BindCppObject( (
void*)gbl->GetAddress(), klass, kTRUE );
974 if ( gbl->GetAddress() &&
975 (
unsigned long)gbl->GetAddress() != (
unsigned long)-1 &&
976 ( gInterpreter->ClassInfo_IsEnum( gbl->GetTypeName() ) ) ) {
977 return PyInt_FromLong( (
long)*((
int*)gbl->GetAddress()) );
981 PyObject* result = (PyObject*)PropertyProxy_New(
982 Cppyy::gGlobalScope, Cppyy::GetDatamemberIndex( Cppyy::gGlobalScope, gbl->GetName() ) );