59 static inline TClass* OP2TCLASS( PyROOT::ObjectProxy* pyobj ) {
60 return TClass::GetClass( Cppyy::GetFinalName( pyobj->ObjectIsA() ).c_str());
66 R__EXTERN PyObject* gRootModule;
72 using namespace PyROOT;
78 Bool_t HasAttrDirect( PyObject* pyclass, PyObject* pyname, Bool_t mustBePyROOT = kFALSE ) {
79 PyObject* attr = PyType_Type.tp_getattro( pyclass, pyname );
80 if ( attr != 0 && ( ! mustBePyROOT || MethodProxy_Check( attr ) ) ) {
92 PyObject* PyObject_GetAttrFromDict( PyObject* pyclass, PyObject* pyname ) {
93 PyObject* dict = PyObject_GetAttr( pyclass, PyStrings::gDict );
94 PyObject* attr = PyObject_GetItem( dict, pyname );
102 inline Bool_t IsTemplatedSTLClass(
const std::string& name,
const std::string& klass ) {
103 const int nsize = (int)name.size();
104 const int ksize = (int)klass.size();
106 return ( ( ksize < nsize && name.substr(0,ksize) == klass ) ||
107 ( ksize+5 < nsize && name.substr(5,ksize) == klass ) ) &&
108 name.find(
"::", name.find(
">" ) ) == std::string::npos;
112 inline PyObject* CallPyObjMethod( PyObject* obj,
const char* meth )
116 PyObject* result = PyObject_CallMethod( obj, const_cast< char* >( meth ), const_cast< char* >(
"" ) );
124 inline PyObject* CallPyObjMethod( PyObject* obj,
const char* meth, PyObject* arg1 )
127 PyObject* result = PyObject_CallMethod(
128 obj, const_cast< char* >( meth ), const_cast< char* >(
"O" ), arg1 );
136 inline PyObject* CallPyObjMethod(
137 PyObject* obj,
const char* meth, PyObject* arg1, PyObject* arg2 )
140 PyObject* result = PyObject_CallMethod(
141 obj, const_cast< char* >( meth ), const_cast< char* >(
"OO" ), arg1, arg2 );
149 inline PyObject* CallPyObjMethod( PyObject* obj,
const char* meth, PyObject* arg1,
int arg2 )
152 PyObject* result = PyObject_CallMethod(
153 obj, const_cast< char* >( meth ), const_cast< char* >(
"Oi" ), arg1, arg2 );
160 PyObject* PyStyleIndex( PyObject*
self, PyObject* index )
163 Py_ssize_t idx = PyInt_AsSsize_t( index );
164 if ( idx == (Py_ssize_t)-1 && PyErr_Occurred() )
167 Py_ssize_t size = PySequence_Size(
self );
168 if ( idx >= size || ( idx < 0 && idx < -size ) ) {
169 PyErr_SetString( PyExc_IndexError,
"index out of range" );
173 PyObject* pyindex = 0;
178 pyindex = PyLong_FromLong( size + idx );
186 inline PyObject* CallSelfIndex( ObjectProxy*
self, PyObject* idx,
const char* meth )
188 Py_INCREF( (PyObject*)
self );
189 PyObject* pyindex = PyStyleIndex( (PyObject*)
self, idx );
191 Py_DECREF( (PyObject*)
self );
195 PyObject* result = CallPyObjMethod( (PyObject*)
self, meth, pyindex );
196 Py_DECREF( pyindex );
197 Py_DECREF( (PyObject*)
self );
204 inline PyObject* BoolNot( PyObject* value )
206 if ( PyObject_IsTrue( value ) == 1 ) {
207 Py_INCREF( Py_False );
211 Py_INCREF( Py_True );
218 PyObject* DeRefGetAttr( PyObject*
self, PyObject* name )
222 if ( ! PyROOT_PyUnicode_Check( name ) )
223 PyErr_SetString( PyExc_TypeError,
"getattr(): attribute name must be string" );
225 PyObject* pyptr = CallPyObjMethod(
self,
"__deref__" );
230 if ( Py_TYPE(pyptr) == Py_TYPE(
self) ) {
231 PyObject* val1 = PyObject_Str(
self );
232 PyObject* val2 = PyObject_Str( name );
233 PyErr_Format( PyExc_AttributeError,
"%s has no attribute \'%s\'",
234 PyROOT_PyUnicode_AsString( val1 ), PyROOT_PyUnicode_AsString( val2 ) );
242 PyObject* result = PyObject_GetAttr( pyptr, name );
251 PyObject* FollowGetAttr( PyObject*
self, PyObject* name )
253 if ( ! PyROOT_PyUnicode_Check( name ) )
254 PyErr_SetString( PyExc_TypeError,
"getattr(): attribute name must be string" );
256 PyObject* pyptr = CallPyObjMethod(
self,
"__follow__" );
260 PyObject* result = PyObject_GetAttr( pyptr, name );
266 PyObject* TObjectContains( PyObject*
self, PyObject* obj )
269 if ( ! ( ObjectProxy_Check( obj ) || PyROOT_PyUnicode_Check( obj ) ) )
270 return PyInt_FromLong( 0l );
272 PyObject* found = CallPyObjMethod(
self,
"FindObject", obj );
273 PyObject* result = PyInt_FromLong( PyObject_IsTrue( found ) );
281 PyObject* TObjectCompare( PyObject*
self, PyObject* obj )
283 if ( ! ObjectProxy_Check( obj ) )
284 return PyInt_FromLong( -1l );
286 return CallPyObjMethod(
self,
"Compare", obj );
292 PyObject* TObjectIsEqual( PyObject*
self, PyObject* obj )
294 if ( ! ObjectProxy_Check( obj ) || ! ((ObjectProxy*)obj)->fObject )
295 return ObjectProxy_Type.tp_richcompare(
self, obj, Py_EQ );
297 return CallPyObjMethod(
self,
"IsEqual", obj );
303 PyObject* TObjectIsNotEqual( PyObject*
self, PyObject* obj )
305 if ( ! ObjectProxy_Check( obj ) || ! ((ObjectProxy*)obj)->fObject )
306 return ObjectProxy_Type.tp_richcompare(
self, obj, Py_NE );
308 return BoolNot( CallPyObjMethod(
self,
"IsEqual", obj ) );
317 PyObject* GenObjectIsEqual( PyObject*
self, PyObject* obj )
319 PyObject* result = CallPyObjMethod(
self,
"__cpp_eq__", obj );
322 result = ObjectProxy_Type.tp_richcompare(
self, obj, Py_EQ );
331 PyObject* GenObjectIsNotEqual( PyObject*
self, PyObject* obj )
333 PyObject* result = CallPyObjMethod(
self,
"__cpp_ne__", obj );
336 result = ObjectProxy_Type.tp_richcompare(
self, obj, Py_NE );
343 PyObject* TClassStaticCast( ObjectProxy*
self, PyObject* args )
347 ObjectProxy* pyclass = 0; PyObject* pyobject = 0;
348 if ( ! PyArg_ParseTuple( args, const_cast< char* >(
"O!O:StaticCast" ),
349 &ObjectProxy_Type, &pyclass, &pyobject ) )
353 TClass* from = (TClass*)OP2TCLASS(
self)->DynamicCast( TClass::Class(), self->GetObject() );
354 TClass* to = (TClass*)OP2TCLASS(
self)->DynamicCast( TClass::Class(), pyclass->GetObject() );
357 PyErr_SetString( PyExc_TypeError,
"unbound method TClass::StaticCast "
358 "must be called with a TClass instance as first argument" );
363 PyErr_SetString( PyExc_TypeError,
"could not convert argument 1 (TClass* expected)" );
369 if ( ObjectProxy_Check( pyobject ) ) address = ((ObjectProxy*)pyobject)->GetObject();
370 else if ( PyInt_Check( pyobject ) || PyLong_Check( pyobject ) ) address = (
void*)PyLong_AsLong( pyobject );
371 else Utility::GetBuffer( pyobject,
'*', 1, address, kFALSE );
374 PyErr_SetString( PyExc_TypeError,
"could not convert argument 2 (void* expected)" );
380 if ( from->InheritsFrom( to ) ) up = 1;
381 else if ( to->InheritsFrom( from ) ) {
382 TClass* tmp = to; to = from; from = tmp;
387 PyErr_Format( PyExc_TypeError,
"unable to cast %s to %s", from->GetName(), to->GetName() );
392 void* result = from->DynamicCast( to, address, (Bool_t)up );
395 return BindCppObjectNoCast( result, Cppyy::GetScope( to->GetName() ) );
403 PyObject* TClassDynamicCast( ObjectProxy*
self, PyObject* args )
405 ObjectProxy* pyclass = 0; PyObject* pyobject = 0;
407 if ( ! PyArg_ParseTuple( args, const_cast< char* >(
"O!O|l:DynamicCast" ),
408 &ObjectProxy_Type, &pyclass, &pyobject, &up ) )
412 PyObject* meth = PyObject_GetAttr( (PyObject*)
self, PyStrings::gTClassDynCast );
413 PyObject* ptr = meth ? PyObject_Call( meth, args, 0 ) : 0;
422 if ( ObjectProxy_Check( pyobject ) ) address = ((ObjectProxy*)pyobject)->GetObject();
423 else if ( PyInt_Check( pyobject ) || PyLong_Check( pyobject ) ) address = (
void*)PyLong_AsLong( pyobject );
424 else Utility::GetBuffer( pyobject,
'*', 1, address, kFALSE );
426 if ( PyErr_Occurred() ) {
434 klass = (TClass*)OP2TCLASS(pyclass)->DynamicCast( TClass::Class(), pyclass->GetObject() );
436 klass = (TClass*)OP2TCLASS(
self)->DynamicCast( TClass::Class(), self->GetObject() );
439 PyObject* result = BindCppObjectNoCast( (
void*)address, Cppyy::GetScope( klass->GetName() ) );
446 PyObject* TCollectionExtend( PyObject*
self, PyObject* obj )
449 for ( Py_ssize_t i = 0; i < PySequence_Size( obj ); ++i ) {
450 PyObject* item = PySequence_GetItem( obj, i );
451 PyObject* result = CallPyObjMethod(
self,
"Add", item );
452 Py_XDECREF( result );
456 Py_INCREF( Py_None );
463 PyObject* TCollectionRemove( PyObject*
self, PyObject* obj )
465 PyObject* result = CallPyObjMethod(
self,
"Remove", obj );
469 if ( ! PyObject_IsTrue( result ) ) {
471 PyErr_SetString( PyExc_ValueError,
"list.remove(x): x not in list" );
476 Py_INCREF( Py_None );
483 PyObject* TCollectionAdd( PyObject*
self, PyObject* other )
485 PyObject* l = CallPyObjMethod(
self,
"Clone" );
489 PyObject* result = CallPyObjMethod( l,
"extend", other );
501 PyObject* TCollectionMul( ObjectProxy*
self, PyObject* pymul )
503 Long_t imul = PyLong_AsLong( pymul );
504 if ( imul == -1 && PyErr_Occurred() )
507 if ( ! self->GetObject() ) {
508 PyErr_SetString( PyExc_TypeError,
"unsubscriptable object" );
512 PyObject* nseq = BindCppObject(
513 Cppyy::Construct( self->ObjectIsA() ), self->ObjectIsA() );
515 for ( Long_t i = 0; i < imul; ++i ) {
516 PyObject* result = CallPyObjMethod( nseq,
"extend", (PyObject*)
self );
526 PyObject* TCollectionIMul( PyObject*
self, PyObject* pymul )
528 Long_t imul = PyLong_AsLong( pymul );
529 if ( imul == -1 && PyErr_Occurred() )
532 PyObject* l = PySequence_List(
self );
534 for ( Long_t i = 0; i < imul - 1; ++i ) {
535 CallPyObjMethod(
self,
"extend", l );
545 PyObject* TCollectionCount( PyObject*
self, PyObject* obj )
547 Py_ssize_t count = 0;
548 for ( Py_ssize_t i = 0; i < PySequence_Size(
self ); ++i ) {
549 PyObject* item = PySequence_GetItem(
self, i );
550 PyObject* found = PyObject_RichCompare( item, obj, Py_EQ );
557 if ( PyObject_IsTrue( found ) )
562 return PyInt_FromSsize_t( count );
568 PyObject* TCollectionIter( ObjectProxy*
self ) {
569 if ( ! self->GetObject() ) {
570 PyErr_SetString( PyExc_TypeError,
"iteration over non-sequence" );
575 (TCollection*)OP2TCLASS(
self)->DynamicCast( TCollection::Class(), self->GetObject() );
577 PyObject* pyobject = BindCppObject( (
void*)
new TIter( col ),
"TIter" );
578 ((ObjectProxy*)pyobject)->HoldOn();
584 PyObject* TSeqCollectionGetItem( ObjectProxy*
self, PySliceObject* index )
587 if ( PySlice_Check( index ) ) {
588 if ( ! self->GetObject() ) {
589 PyErr_SetString( PyExc_TypeError,
"unsubscriptable object" );
593 TClass* clSeq = OP2TCLASS(
self);
594 TSeqCollection* oseq =
595 (TSeqCollection*)clSeq->DynamicCast( TSeqCollection::Class(), self->GetObject() );
596 TSeqCollection* nseq = (TSeqCollection*)clSeq->New();
598 Py_ssize_t start, stop, step;
599 PySlice_GetIndices( (PyROOT_PySliceCast)index, oseq->GetSize(), &start, &stop, &step );
601 for ( Py_ssize_t i = start; i < stop; i += step ) {
602 nseq->Add( oseq->At( (Int_t)i ) );
605 return BindCppObject( (
void*) nseq, clSeq->GetName() );
608 return CallSelfIndex(
self, (PyObject*)index,
"At" );
614 PyObject* TSeqCollectionSetItem( ObjectProxy*
self, PyObject* args )
616 PyObject* index = 0, *obj = 0;
617 if ( ! PyArg_ParseTuple( args,
618 const_cast< char* >(
"OO:__setitem__" ), &index, &obj ) )
621 if ( PySlice_Check( index ) ) {
622 if ( ! self->GetObject() ) {
623 PyErr_SetString( PyExc_TypeError,
"unsubscriptable object" );
627 TSeqCollection* oseq = (TSeqCollection*)OP2TCLASS(
self)->DynamicCast(
628 TSeqCollection::Class(), self->GetObject() );
630 Py_ssize_t start, stop, step;
631 PySlice_GetIndices( (PyROOT_PySliceCast)index, oseq->GetSize(), &start, &stop, &step );
632 for ( Py_ssize_t i = stop - step; i >= start; i -= step ) {
633 oseq->RemoveAt( (Int_t)i );
636 for ( Py_ssize_t i = 0; i < PySequence_Size( obj ); ++i ) {
637 ObjectProxy* item = (ObjectProxy*)PySequence_GetItem( obj, i );
639 oseq->AddAt( (TObject*) item->GetObject(), (Int_t)(i + start) );
643 Py_INCREF( Py_None );
647 PyObject* pyindex = PyStyleIndex( (PyObject*)
self, index );
651 PyObject* result = CallPyObjMethod( (PyObject*)
self,
"RemoveAt", pyindex );
653 Py_DECREF( pyindex );
658 result = CallPyObjMethod( (PyObject*)
self,
"AddAt", obj, pyindex );
659 Py_DECREF( pyindex );
666 PyObject* TSeqCollectionDelItem( ObjectProxy*
self, PySliceObject* index )
668 if ( PySlice_Check( index ) ) {
669 if ( ! self->GetObject() ) {
670 PyErr_SetString( PyExc_TypeError,
"unsubscriptable object" );
674 TSeqCollection* oseq = (TSeqCollection*)OP2TCLASS(
self)->DynamicCast(
675 TSeqCollection::Class(), self->GetObject() );
677 Py_ssize_t start, stop, step;
678 PySlice_GetIndices( (PyROOT_PySliceCast)index, oseq->GetSize(), &start, &stop, &step );
679 for ( Py_ssize_t i = stop - step; i >= start; i -= step ) {
680 oseq->RemoveAt( (Int_t)i );
683 Py_INCREF( Py_None );
687 PyObject* result = CallSelfIndex(
self, (PyObject*)index,
"RemoveAt" );
692 Py_INCREF( Py_None );
699 PyObject* TSeqCollectionInsert( PyObject*
self, PyObject* args )
701 PyObject* obj = 0; Long_t idx = 0;
702 if ( ! PyArg_ParseTuple( args, const_cast< char* >(
"lO:insert" ), &idx, &obj ) )
705 Py_ssize_t size = PySequence_Size(
self );
708 else if ( size < idx )
711 return CallPyObjMethod(
self,
"AddAt", obj, idx );
717 PyObject* TSeqCollectionPop( ObjectProxy*
self, PyObject* args )
719 int nArgs = PyTuple_GET_SIZE( args );
722 PyObject* index = PyInt_FromSsize_t( PySequence_Size( (PyObject*)
self ) - 1 );
723 PyObject* result = CallSelfIndex(
self, index,
"RemoveAt" );
726 }
else if ( nArgs != 1 ) {
727 PyErr_Format( PyExc_TypeError,
728 "pop() takes at most 1 argument (%d given)", nArgs );
732 return CallSelfIndex(
self, PyTuple_GET_ITEM( args, 0 ),
"RemoveAt" );
738 PyObject* TSeqCollectionReverse( PyObject*
self )
740 PyObject* tup = PySequence_Tuple(
self );
744 PyObject* result = CallPyObjMethod(
self,
"Clear" );
745 Py_XDECREF( result );
747 for ( Py_ssize_t i = 0; i < PySequence_Size( tup ); ++i ) {
748 PyObject* retval = CallPyObjMethod(
self,
"AddAt", PyTuple_GET_ITEM( tup, i ), 0 );
749 Py_XDECREF( retval );
752 Py_INCREF( Py_None );
759 PyObject* TSeqCollectionSort( PyObject*
self, PyObject* args, PyObject* kw )
761 if ( PyTuple_GET_SIZE( args ) == 0 && ! kw ) {
763 return CallPyObjMethod(
self,
"Sort" );
766 PyObject* l = PySequence_List(
self );
767 PyObject* result = 0;
768 if ( PyTuple_GET_SIZE( args ) == 1 )
769 result = CallPyObjMethod( l,
"sort", PyTuple_GET_ITEM( args, 0 ) );
771 PyObject* pymeth = PyObject_GetAttrString( l, const_cast< char* >(
"sort" ) );
772 result = PyObject_Call( pymeth, args, kw );
776 Py_XDECREF( result );
777 if ( PyErr_Occurred() ) {
782 result = CallPyObjMethod(
self,
"Clear" );
783 Py_XDECREF( result );
784 result = CallPyObjMethod(
self,
"extend", l );
785 Py_XDECREF( result );
788 Py_INCREF( Py_None );
796 PyObject* TSeqCollectionIndex( PyObject*
self, PyObject* obj )
798 PyObject* index = CallPyObjMethod(
self,
"IndexOf", obj );
802 if ( PyLong_AsLong( index ) < 0 ) {
804 PyErr_SetString( PyExc_ValueError,
"list.index(x): x not in list" );
812 PyObject* TObjArrayLen( PyObject*
self )
815 PyObject* size = CallPyObjMethod(
self,
"GetLast" );
819 long lsize = PyLong_AsLong( size );
820 if ( lsize == -1 && PyErr_Occurred() )
824 return PyInt_FromLong( lsize + 1 );
829 PyObject* TClonesArraySetItem( ObjectProxy*
self, PyObject* args )
834 ObjectProxy* pyobj = 0; PyObject* idx = 0;
835 if ( ! PyArg_ParseTuple( args,
836 const_cast< char* >(
"OO!:__setitem__" ), &idx, &ObjectProxy_Type, &pyobj ) )
839 if ( ! self->GetObject() ) {
840 PyErr_SetString( PyExc_TypeError,
"unsubscriptable object" );
844 PyObject* pyindex = PyStyleIndex( (PyObject*)
self, idx );
847 int index = (int)PyLong_AsLong( pyindex );
848 Py_DECREF( pyindex );
852 (TClonesArray*)OP2TCLASS(
self)->DynamicCast( TClonesArray::Class(), self->GetObject() );
855 PyErr_SetString( PyExc_TypeError,
"attempt to call with null object" );
859 if ( Cppyy::GetScope( cla->GetClass()->GetName() ) != pyobj->ObjectIsA() ) {
860 PyErr_Format( PyExc_TypeError,
"require object of type %s, but %s given",
861 cla->GetClass()->GetName(), Cppyy::GetFinalName( pyobj->ObjectIsA() ).c_str() );
865 if ( ((
const TClonesArray&)*cla)[index] ) {
866 cla->RemoveAt( index );
869 if ( pyobj->GetObject() ) {
871 TObject*
object = (*cla)[index];
873 TMemoryRegulator::RegisterObject( pyobj,
object );
874 memcpy( (
void*)
object, pyobj->GetObject(), cla->GetClass()->Size() );
877 Py_INCREF( Py_None );
886 PyROOT::TConverter* vi_converter;
889 Py_ssize_t vi_stride;
892 static void vectoriter_dealloc( vectoriterobject* vi ) {
893 Py_XDECREF( vi->vi_vector );
894 delete vi->vi_converter;
895 PyObject_GC_Del( vi );
898 static int vectoriter_traverse( vectoriterobject* vi, visitproc visit,
void* arg ) {
899 Py_VISIT( vi->vi_vector );
903 static PyObject* vectoriter_iternext( vectoriterobject* vi ) {
904 if ( vi->vi_pos >= vi->vi_len )
907 PyObject* result =
nullptr;
909 if ( vi->vi_data && vi->vi_converter ) {
910 void* location = (
void*)((ptrdiff_t)vi->vi_data + vi->vi_stride * vi->vi_pos );
911 result = vi->vi_converter->FromMemory( location );
913 PyObject* pyindex = PyLong_FromLong( vi->vi_pos );
914 result = CallPyObjMethod( (PyObject*)vi->vi_vector,
"_vector__at", pyindex );
915 Py_DECREF( pyindex );
922 PyTypeObject VectorIter_Type = {
923 PyVarObject_HEAD_INIT( &PyType_Type, 0 )
924 (
char*)
"ROOT.vectoriter",
925 sizeof(vectoriterobject),
927 (destructor)vectoriter_dealloc,
928 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
932 (traverseproc)vectoriter_traverse,
935 (iternextfunc)vectoriter_iternext,
937 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
938 #
if PY_VERSION_HEX >= 0x02030000
941 #
if PY_VERSION_HEX >= 0x02060000
944 #
if PY_VERSION_HEX >= 0x03040000
949 static PyObject* vector_iter( PyObject* v ) {
950 vectoriterobject* vi = PyObject_GC_New( vectoriterobject, &VectorIter_Type );
951 if ( ! vi )
return NULL;
956 PyObject* pyvalue_type = PyObject_GetAttrString( (PyObject*)Py_TYPE(v),
"value_type" );
957 PyObject* pyvalue_size = PyObject_GetAttrString( (PyObject*)Py_TYPE(v),
"value_size" );
959 if ( pyvalue_type && pyvalue_size ) {
960 PyObject* pydata = CallPyObjMethod( v,
"data" );
961 if ( !pydata || Utility::GetBuffer( pydata,
'*', 1, vi->vi_data, kFALSE ) == 0 )
962 vi->vi_data =
nullptr;
963 Py_XDECREF( pydata );
965 vi->vi_converter = PyROOT::CreateConverter( PyROOT_PyUnicode_AsString( pyvalue_type ) );
966 vi->vi_stride = PyLong_AsLong( pyvalue_size );
969 vi->vi_data =
nullptr;
970 vi->vi_converter =
nullptr;
974 Py_XDECREF( pyvalue_size );
975 Py_XDECREF( pyvalue_type );
977 vi->vi_len = vi->vi_pos = 0;
978 vi->vi_len = PySequence_Size( v );
980 PyObject_GC_Track( vi );
981 return (PyObject*)vi;
985 PyObject* VectorGetItem( ObjectProxy*
self, PySliceObject* index )
988 if ( PySlice_Check( index ) ) {
989 if ( ! self->GetObject() ) {
990 PyErr_SetString( PyExc_TypeError,
"unsubscriptable object" );
994 PyObject* pyclass = PyObject_GetAttr( (PyObject*)
self, PyStrings::gClass );
995 PyObject* nseq = PyObject_CallObject( pyclass, NULL );
996 Py_DECREF( pyclass );
998 Py_ssize_t start, stop, step;
999 PySlice_GetIndices( (PyROOT_PySliceCast)index, PyObject_Length( (PyObject*)
self ), &start, &stop, &step );
1000 for ( Py_ssize_t i = start; i < stop; i += step ) {
1001 PyObject* pyidx = PyInt_FromSsize_t( i );
1002 CallPyObjMethod( nseq,
"push_back", CallPyObjMethod( (PyObject*)
self,
"_vector__at", pyidx ) );
1009 return CallSelfIndex(
self, (PyObject*)index,
"_vector__at" );
1012 PyObject* VectorBoolSetItem( ObjectProxy*
self, PyObject* args )
1016 int bval = 0; PyObject* idx = 0;
1017 if ( ! PyArg_ParseTuple( args, const_cast< char* >(
"Oi:__setitem__" ), &idx, &bval ) )
1020 if ( ! self->GetObject() ) {
1021 PyErr_SetString( PyExc_TypeError,
"unsubscriptable object" );
1025 PyObject* pyindex = PyStyleIndex( (PyObject*)
self, idx );
1028 int index = (int)PyLong_AsLong( pyindex );
1029 Py_DECREF( pyindex );
1031 std::string clName = Cppyy::GetFinalName( self->ObjectIsA() );
1032 std::string::size_type pos = clName.find(
"vector<bool" );
1033 if ( pos != 0 && pos != 5 ) {
1034 PyErr_Format( PyExc_TypeError,
1035 "require object of type std::vector<bool>, but %s given",
1036 Cppyy::GetFinalName( self->ObjectIsA() ).c_str() );
1041 std::vector<bool>* vb = (std::vector<bool>*)self->GetObject();
1044 (*vb)[ index ] = (bool)bval;
1046 Py_INCREF( Py_None );
1051 PyObject* MapContains( PyObject*
self, PyObject* obj )
1054 PyObject* result = 0;
1056 PyObject* iter = CallPyObjMethod(
self,
"find", obj );
1057 if ( ObjectProxy_Check( iter ) ) {
1058 PyObject* end = CallPyObjMethod(
self,
"end" );
1059 if ( ObjectProxy_Check( end ) ) {
1060 if ( ! PyObject_RichCompareBool( iter, end, Py_EQ ) ) {
1061 Py_INCREF( Py_True );
1071 Py_INCREF( Py_False );
1079 PyObject* StlSequenceIter( PyObject*
self )
1082 PyObject* iter = CallPyObjMethod(
self,
"begin" );
1084 PyObject* end = CallPyObjMethod(
self,
"end" );
1086 PyObject_SetAttr( iter, PyStrings::gEnd, end );
1090 PyObject_SetAttr( iter, PyUnicode_FromString(
"_collection"),
self );
1096 PyObject* CheckedGetItem( PyObject*
self, PyObject* obj )
1101 Bool_t inbounds = kFALSE;
1102 Py_ssize_t size = PySequence_Size(
self );
1103 Py_ssize_t idx = PyInt_AsSsize_t( obj );
1104 if ( 0 <= idx && 0 <= size && idx < size )
1108 return CallPyObjMethod(
self,
"_getitem__unchecked", obj );
1109 }
else if ( PyErr_Occurred() ) {
1112 return CallPyObjMethod(
self,
"_getitem__unchecked", obj );
1114 PyErr_SetString( PyExc_IndexError,
"index out of range" );
1121 PyObject* PairUnpack( PyObject*
self, PyObject* pyindex )
1124 Long_t idx = PyLong_AsLong( pyindex );
1125 if ( idx == -1 && PyErr_Occurred() )
1128 if ( ! ObjectProxy_Check(
self ) || ! ((ObjectProxy*)
self)->GetObject() ) {
1129 PyErr_SetString( PyExc_TypeError,
"unsubscriptable object" );
1133 if ( (
int)idx == 0 )
1134 return PyObject_GetAttr(
self, PyStrings::gFirst );
1135 else if ( (
int)idx == 1 )
1136 return PyObject_GetAttr(
self, PyStrings::gSecond );
1139 PyErr_SetString( PyExc_IndexError,
"out of bounds" );
1144 #if PY_VERSION_HEX >= 0x03000000
1146 static int PyObject_Compare( PyObject* one, PyObject* other ) {
1147 return ! PyObject_RichCompareBool( one, other, Py_EQ );
1150 static inline PyObject* PyROOT_PyString_FromCppString( std::string* s ) {
1151 return PyROOT_PyUnicode_FromStringAndSize( s->c_str(), s->size() );
1154 static inline PyObject* PyROOT_PyString_FromCppString( TString* s ) {
1155 return PyROOT_PyUnicode_FromStringAndSize( s->Data(), s->Length() );
1158 static inline PyObject* PyROOT_PyString_FromCppString( TObjString* s ) {
1159 return PyROOT_PyUnicode_FromStringAndSize( s->GetString().Data(), s->GetString().Length() );
1162 #define PYROOT_IMPLEMENT_STRING_PYTHONIZATION( type, name ) \
1163 inline PyObject* name##GetData( PyObject* self ) { \
1164 if ( PyROOT::ObjectProxy_Check( self ) ) { \
1165 type* obj = ((type*)((ObjectProxy*)self)->GetObject()); \
1167 return PyROOT_PyString_FromCppString( obj ); \
1169 return ObjectProxy_Type.tp_str( self ); \
1172 PyErr_Format( PyExc_TypeError, "object mismatch (%s expected)", #type );\
1176 PyObject* name##StringRepr( PyObject* self ) \
1178 PyObject* data = name##GetData( self ); \
1180 PyObject* repr = PyROOT_PyUnicode_FromFormat( "\'%s\'", PyROOT_PyUnicode_AsString( data ) ); \
1181 Py_DECREF( data ); \
1187 PyObject* name##StringIsEqual( PyObject* self, PyObject* obj ) \
1189 PyObject* data = name##GetData( self ); \
1191 PyObject* result = PyObject_RichCompare( data, obj, Py_EQ ); \
1192 Py_DECREF( data ); \
1198 PyObject* name##StringIsNotEqual( PyObject* self, PyObject* obj ) \
1200 PyObject* data = name##GetData( self ); \
1202 PyObject* result = PyObject_RichCompare( data, obj, Py_NE ); \
1203 Py_DECREF( data ); \
1211 #define PYROOT_IMPLEMENT_STRING_PYTHONIZATION_CMP( type, name ) \
1212 PYROOT_IMPLEMENT_STRING_PYTHONIZATION( type, name ) \
1213 PyObject* name##StringCompare( PyObject* self, PyObject* obj ) \
1215 PyObject* data = name##GetData( self ); \
1218 result = PyObject_Compare( data, obj ); \
1219 Py_DECREF( data ); \
1221 if ( PyErr_Occurred() ) \
1223 return PyInt_FromLong( result ); \
1226 PYROOT_IMPLEMENT_STRING_PYTHONIZATION_CMP( std::string, Stl )
1227 PYROOT_IMPLEMENT_STRING_PYTHONIZATION( TString, T )
1231 PYROOT_IMPLEMENT_STRING_PYTHONIZATION_CMP( TObjString, TObj )
1236 PyObject* TObjStringLength( PyObject* self )
1238 PyObject* data = CallPyObjMethod(
self,
"GetName" );
1239 Py_ssize_t size = PySequence_Size( data );
1241 return PyInt_FromSsize_t( size );
1246 PyObject* TIterNext( PyObject*
self )
1249 PyObject* next = CallPyObjMethod(
self,
"Next" );
1254 if ( ! PyObject_IsTrue( next ) ) {
1256 PyErr_SetString( PyExc_StopIteration,
"" );
1265 PyObject* StlIterNext( PyObject*
self )
1269 PyObject* last = PyObject_GetAttr(
self, PyStrings::gEnd );
1273 if ( PyObject_RichCompareBool( last,
self, Py_EQ ) ) {
1274 PyErr_SetString( PyExc_StopIteration,
"" );
1276 PyObject* dummy = PyInt_FromLong( 1l );
1277 PyObject* iter = CallPyObjMethod(
self,
"__postinc__", dummy );
1280 if ( PyObject_RichCompareBool( last, iter, Py_EQ ) )
1281 PyErr_SetString( PyExc_StopIteration,
"" );
1283 next = CallPyObjMethod( iter,
"__deref__" );
1285 PyErr_SetString( PyExc_StopIteration,
"" );
1290 PyErr_SetString( PyExc_StopIteration,
"" );
1301 PyObject* StlIterIsEqual( PyObject*
self, PyObject* other )
1303 if (other != Py_None) {
1304 if (Utility::AddBinaryOperator(
self, other,
"==",
"__eq__",
nullptr,
true))
1305 return PyObject_CallMethodObjArgs(
self, PyStrings::gEq, other,
nullptr);
1308 return PyErr_Format( PyExc_LookupError,
1309 "No operator==(const %s&, const %s&) available in the dictionary!",
1310 Utility::ClassName(
self ).c_str(), Utility::ClassName( other ).c_str() );
1317 PyObject* StlIterIsNotEqual( PyObject*
self, PyObject* other )
1319 if (other != Py_None) {
1320 if (Utility::AddBinaryOperator(
self, other,
"!=",
"__ne__",
nullptr,
true))
1321 return PyObject_CallMethodObjArgs(
self, PyStrings::gNe, other,
nullptr);
1324 return PyErr_Format( PyExc_LookupError,
1325 "No operator!=(const %s&, const %s&) available in the dictionary!",
1326 Utility::ClassName(
self ).c_str(), Utility::ClassName( other ).c_str() );
1331 PyObject* TDirectoryGetObject( ObjectProxy*
self, PyObject* args )
1334 PyObject* name = 0; ObjectProxy* ptr = 0;
1335 if ( ! PyArg_ParseTuple( args, const_cast< char* >(
"O!O!:TDirectory::GetObject" ),
1336 &PyROOT_PyUnicode_Type, &name, &ObjectProxy_Type, &ptr ) )
1340 (TDirectory*)OP2TCLASS(
self)->DynamicCast( TDirectory::Class(), self->GetObject() );
1343 PyErr_SetString( PyExc_TypeError,
1344 "TDirectory::GetObject must be called with a TDirectory instance as first argument" );
1348 void* address = dir->GetObjectChecked( PyROOT_PyUnicode_AsString( name ), OP2TCLASS(ptr) );
1350 ptr->Set( address );
1352 Py_INCREF( Py_None );
1356 PyErr_Format( PyExc_LookupError,
"no such object, \"%s\"", PyROOT_PyUnicode_AsString( name ) );
1364 PyObject* TDirectoryWriteObject( ObjectProxy*
self, PyObject* args )
1366 ObjectProxy *wrt = 0; PyObject *name = 0, *option = 0;
1368 if ( ! PyArg_ParseTuple( args, const_cast< char* >(
"O!O!|O!i:TDirectory::WriteObject" ),
1369 &ObjectProxy_Type, &wrt, &PyROOT_PyUnicode_Type, &name,
1370 &PyROOT_PyUnicode_Type, &option, &bufsize ) )
1374 (TDirectory*)OP2TCLASS(
self)->DynamicCast( TDirectory::Class(), self->GetObject() );
1377 PyErr_SetString( PyExc_TypeError,
1378 "TDirectory::WriteObject must be called with a TDirectory instance as first argument" );
1383 if ( option != 0 ) {
1384 result = dir->WriteObjectAny( wrt->GetObject(), OP2TCLASS(wrt),
1385 PyROOT_PyUnicode_AsString( name ), PyROOT_PyUnicode_AsString( option ), bufsize );
1387 result = dir->WriteObjectAny(
1388 wrt->GetObject(), OP2TCLASS(wrt), PyROOT_PyUnicode_AsString( name ) );
1391 return PyInt_FromLong( (Long_t)result );
1400 PyObject* TTreeGetAttr( ObjectProxy*
self, PyObject* pyname )
1403 const char* name1 = PyROOT_PyUnicode_AsString( pyname );
1409 (TTree*)OP2TCLASS(
self)->DynamicCast( TTree::Class(), self->GetObject() );
1412 PyErr_SetString( PyExc_ReferenceError,
"attempt to access a null-pointer" );
1417 const char* name = tree->GetAlias( name1 );
1418 if ( ! name ) name = name1;
1421 TBranch* branch = tree->GetBranch( name );
1424 branch = tree->GetBranch( (std::string( name ) +
'.' ).c_str() );
1431 if ( branch->InheritsFrom(TBranchElement::Class()) ) {
1432 TBranchElement* be = (TBranchElement*)branch;
1433 if ( be->GetCurrentClass() && (be->GetCurrentClass() != be->GetTargetClass()) && (0 <= be->GetID()) ) {
1434 Long_t offset = ((TStreamerElement*)be->GetInfo()->GetElements()->At(be->GetID()))->GetOffset();
1435 return BindCppObjectNoCast( be->GetObject() + offset, Cppyy::GetScope( be->GetCurrentClass()->GetName() ) );
1440 if ( branch->IsA() == TBranchElement::Class() || branch->IsA() == TBranchObject::Class() ) {
1441 TClass* klass = TClass::GetClass( branch->GetClassName() );
1442 if ( klass && branch->GetAddress() )
1443 return BindCppObjectNoCast( *(
void**)branch->GetAddress(), Cppyy::GetScope( branch->GetClassName() ) );
1446 TObjArray* leaves = branch->GetListOfLeaves();
1447 if ( klass && ! tree->GetLeaf( name ) &&
1448 ! (leaves->GetSize() && ( leaves->First() == leaves->Last() ) ) )
1449 return BindCppObjectNoCast( NULL, Cppyy::GetScope( branch->GetClassName() ) );
1454 TLeaf* leaf = tree->GetLeaf( name );
1455 if ( branch && ! leaf ) {
1456 leaf = branch->GetLeaf( name );
1458 TObjArray* leaves = branch->GetListOfLeaves();
1459 if ( leaves->GetSize() && ( leaves->First() == leaves->Last() ) ) {
1461 leaf = (TLeaf*)leaves->At( 0 );
1468 if ( 1 < leaf->GetLenStatic() || leaf->GetLeafCount() ) {
1470 std::string typeName = leaf->GetTypeName();
1471 TConverter* pcnv = CreateConverter( typeName +
'*', leaf->GetNdata() );
1474 if ( leaf->GetBranch() ) address = (
void*)leaf->GetBranch()->GetAddress();
1475 if ( ! address ) address = (
void*)leaf->GetValuePointer();
1477 PyObject* value = pcnv->FromMemory( &address );
1481 }
else if ( leaf->GetValuePointer() ) {
1483 TConverter* pcnv = CreateConverter( leaf->GetTypeName() );
1484 PyObject* value = 0;
1485 if ( leaf->IsA() == TLeafElement::Class() || leaf->IsA() == TLeafObject::Class() )
1486 value = pcnv->FromMemory( (
void*)*(
void**)leaf->GetValuePointer() );
1488 value = pcnv->FromMemory( (
void*)leaf->GetValuePointer() );
1496 PyErr_Format( PyExc_AttributeError,
1497 "\'%s\' object has no attribute \'%s\'", tree->IsA()->GetName(), name );
1503 class TTreeMemberFunction :
public PyCallable {
1505 TTreeMemberFunction( MethodProxy* org ) { Py_INCREF( org ); fOrg = org; }
1506 TTreeMemberFunction(
const TTreeMemberFunction& t ) : PyCallable( t )
1509 Py_INCREF( t.fOrg );
1512 TTreeMemberFunction& operator=(
const TTreeMemberFunction& t )
1516 Py_INCREF( t.fOrg );
1522 ~TTreeMemberFunction() { Py_DECREF( fOrg ); fOrg = 0; }
1525 virtual PyObject* GetSignature() {
return PyROOT_PyUnicode_FromString(
"(...)" ); }
1526 virtual PyObject* GetPrototype() {
return PyObject_GetAttrString( (PyObject*)fOrg, (
char*)
"__doc__" ); }
1527 virtual Int_t GetPriority() {
return 100; }
1528 virtual PyObject* GetCoVarNames() {
1529 PyObject* co_varnames = PyTuple_New( 1 + 1 );
1530 PyTuple_SET_ITEM( co_varnames, 0, PyROOT_PyUnicode_FromString(
"self" ) );
1531 PyTuple_SET_ITEM( co_varnames, 1, PyROOT_PyUnicode_FromString(
"*args" ) );
1534 virtual PyObject* GetArgDefault( Int_t ) {
return NULL; }
1535 virtual PyObject* GetScopeProxy() {
return CreateScopeProxy(
"TTree" ); }
1543 class TTreeBranch :
public TTreeMemberFunction {
1545 TTreeBranch( MethodProxy* org ) : TTreeMemberFunction( org ) {}
1548 virtual Int_t GetMaxArgs() {
return 5; }
1549 virtual PyCallable* Clone() {
return new TTreeBranch( *
this ); }
1551 virtual PyObject* Call(
1552 ObjectProxy*&
self, PyObject* args, PyObject* kwds, TCallContext* )
1558 int argc = PyTuple_GET_SIZE( args );
1562 (TTree*)OP2TCLASS(
self)->DynamicCast( TTree::Class(), self->GetObject() );
1565 PyErr_SetString( PyExc_TypeError,
1566 "TTree::Branch must be called with a TTree instance as first argument" );
1570 PyObject *name = 0, *clName = 0, *leaflist = 0;
1571 PyObject *address = 0;
1572 PyObject *bufsize = 0, *splitlevel = 0;
1575 if ( PyArg_ParseTuple( args, const_cast< char* >(
"O!OO!|O!:Branch" ),
1576 &PyROOT_PyUnicode_Type, &name, &address, &PyROOT_PyUnicode_Type,
1577 &leaflist, &PyInt_Type, &bufsize ) ) {
1580 if ( ObjectProxy_Check( address ) )
1581 buf = (
void*)((ObjectProxy*)address)->GetObject();
1583 Utility::GetBuffer( address,
'*', 1, buf, kFALSE );
1586 TBranch* branch = 0;
1588 branch = tree->Branch( PyROOT_PyUnicode_AsString( name ), buf,
1589 PyROOT_PyUnicode_AsString( leaflist ), PyInt_AS_LONG( bufsize ) );
1591 branch = tree->Branch( PyROOT_PyUnicode_AsString( name ), buf,
1592 PyROOT_PyUnicode_AsString( leaflist ) );
1595 return BindCppObject( branch,
"TBranch" );
1603 Bool_t bIsMatch = kFALSE;
1604 if ( PyArg_ParseTuple( args, const_cast< char* >(
"O!O!O|O!O!:Branch" ),
1605 &PyROOT_PyUnicode_Type, &name, &PyROOT_PyUnicode_Type, &clName, &address,
1606 &PyInt_Type, &bufsize, &PyInt_Type, &splitlevel ) ) {
1609 PyErr_Clear(); clName = 0;
1610 if ( PyArg_ParseTuple( args, const_cast< char* >(
"O!O|O!O!" ),
1611 &PyROOT_PyUnicode_Type, &name, &address,
1612 &PyInt_Type, &bufsize, &PyInt_Type, &splitlevel ) ) {
1618 if ( bIsMatch == kTRUE ) {
1619 std::string klName = clName ? PyROOT_PyUnicode_AsString( clName ) :
"";
1622 if ( ObjectProxy_Check( address ) ) {
1623 if ( ((ObjectProxy*)address)->fFlags & ObjectProxy::kIsReference )
1624 buf = (
void*)((ObjectProxy*)address)->fObject;
1626 buf = (
void*)&((ObjectProxy*)address)->fObject;
1629 klName = OP2TCLASS((ObjectProxy*)address)->GetName();
1633 Utility::GetBuffer( address,
'*', 1, buf, kFALSE );
1635 if ( buf != 0 && klName !=
"" ) {
1636 TBranch* branch = 0;
1638 branch = tree->Branch( PyROOT_PyUnicode_AsString( name ), klName.c_str(), buf );
1639 }
else if ( argc == 4 ) {
1640 branch = tree->Branch( PyROOT_PyUnicode_AsString( name ), klName.c_str(), buf,
1641 PyInt_AS_LONG( bufsize ) );
1642 }
else if ( argc == 5 ) {
1643 branch = tree->Branch( PyROOT_PyUnicode_AsString( name ), klName.c_str(), buf,
1644 PyInt_AS_LONG( bufsize ), PyInt_AS_LONG( splitlevel ) );
1647 return BindCppObject( branch,
"TBranch" );
1653 Py_INCREF( (PyObject*)
self );
1655 PyObject* result = PyObject_Call( (PyObject*)fOrg, args, kwds );
1657 Py_DECREF( (PyObject*)
self );
1665 class TTreeSetBranchAddress :
public TTreeMemberFunction {
1667 TTreeSetBranchAddress( MethodProxy* org ) : TTreeMemberFunction( org ) {}
1670 virtual PyObject* GetPrototype()
1672 return PyROOT_PyUnicode_FromString(
"TBranch* TTree::SetBranchAddress( ... )" );
1675 virtual Int_t GetMaxArgs() {
return 2; }
1676 virtual PyCallable* Clone() {
return new TTreeSetBranchAddress( *
this ); }
1678 virtual PyObject* Call(
1679 ObjectProxy*&
self, PyObject* args, PyObject* kwds, TCallContext* )
1683 int argc = PyTuple_GET_SIZE( args );
1687 (TTree*)OP2TCLASS(
self)->DynamicCast( TTree::Class(), self->GetObject() );
1690 PyErr_SetString( PyExc_TypeError,
1691 "TTree::SetBranchAddress must be called with a TTree instance as first argument" );
1695 PyObject *name = 0, *address = 0;
1698 if ( PyArg_ParseTuple( args, const_cast< char* >(
"SO:SetBranchAddress" ),
1699 &name, &address ) ) {
1702 if ( ObjectProxy_Check( address ) ) {
1703 if ( ((ObjectProxy*)address)->fFlags & ObjectProxy::kIsReference )
1704 buf = (
void*)((ObjectProxy*)address)->fObject;
1706 buf = (
void*)&((ObjectProxy*)address)->fObject;
1708 Utility::GetBuffer( address,
'*', 1, buf, kFALSE );
1711 tree->SetBranchAddress( PyROOT_PyUnicode_AsString( name ), buf );
1713 Py_INCREF( Py_None );
1720 Py_INCREF( (PyObject*)
self );
1722 PyObject* result = PyObject_Call( (PyObject*)fOrg, args, kwds );
1724 Py_DECREF( (PyObject*)
self );
1730 virtual PyObject* ReportTypeError()
1732 PyErr_SetString( PyExc_TypeError,
1733 "TTree::SetBranchAddress must be called with a TTree instance as first argument" );
1741 class TChainSetBranchAddress :
public TTreeSetBranchAddress {
1743 TChainSetBranchAddress( MethodProxy* org ) : TTreeSetBranchAddress( org ) {}
1746 virtual PyObject* GetPrototype()
1748 return PyROOT_PyUnicode_FromString(
"TBranch* TChain::SetBranchAddress( ... )" );
1751 virtual Int_t GetMaxArgs() {
return 2; }
1752 virtual PyCallable* Clone() {
return new TChainSetBranchAddress( *
this ); }
1755 virtual PyObject* ReportTypeError()
1757 PyErr_SetString( PyExc_TypeError,
1758 "TChain::SetBranchAddress must be called with a TChain instance as first argument" );
1764 void TMinuitPyCallback(
void* vpyfunc, Long_t ,
1765 Int_t& a0, Double_t* a1, Double_t& a2, Double_t* a3, Int_t a4 ) {
1767 PyObject* pyfunc = (PyObject*)vpyfunc;
1770 PyObject* pya0 = BufFac_t::Instance()->PyBuffer_FromMemory( &a0,
sizeof(Int_t) );
1771 PyObject* pya1 = BufFac_t::Instance()->PyBuffer_FromMemory( a1, a0 *
sizeof(Double_t) );
1772 PyObject* pya2 = BufFac_t::Instance()->PyBuffer_FromMemory( &a2,
sizeof(Double_t) );
1773 PyObject* pya3 = BufFac_t::Instance()->PyBuffer_FromMemory( a3, -1 );
1775 if ( ! (pya0 && pya1 && pya2 && pya3) ) {
1776 Py_XDECREF( pya3 ); Py_XDECREF( pya2 ); Py_XDECREF( pya1 ); Py_XDECREF( pya0 );
1781 PyObject* result = PyObject_CallFunction(
1782 pyfunc, (
char*)
"OOOOi", pya0, pya1, pya2, pya3, a4 );
1783 Py_DECREF( pya3 ); Py_DECREF( pya2 ); Py_DECREF( pya1 ); Py_DECREF( pya0 );
1787 throw std::runtime_error(
"TMinuit python fit function call failed" );
1790 Py_XDECREF( result );
1794 double TFNPyCallback(
void* vpyfunc, Long_t npar,
double* a0,
double* a1 ) {
1796 PyObject* pyfunc = (PyObject*)vpyfunc;
1799 PyObject* pya0 = BufFac_t::Instance()->PyBuffer_FromMemory( a0, 4 *
sizeof(
double) );
1803 PyObject* result = 0;
1805 PyObject* pya1 = BufFac_t::Instance()->PyBuffer_FromMemory( a1, npar *
sizeof(
double) );
1806 result = PyObject_CallFunction( pyfunc, (
char*)
"OO", pya0, pya1 );
1809 result = PyObject_CallFunction( pyfunc, (
char*)
"O", pya0 );
1817 throw std::runtime_error(
"TFN python function call failed" );
1819 d = PyFloat_AsDouble( result );
1820 Py_DECREF( result );
1832 using namespace PyROOT;
1835 PyObject* THNIMul( PyObject*
self, PyObject* scale )
1838 PyObject* result = CallPyObjMethod(
self,
"Scale", scale );
1842 Py_DECREF( result );
1850 class TPretendInterpreted:
public PyCallable {
1852 TPretendInterpreted(
int nArgs ) : fNArgs( nArgs ) {}
1855 Int_t GetNArgs() {
return fNArgs; }
1856 virtual Int_t GetPriority() {
return 100; }
1857 virtual Int_t GetMaxArgs() {
return GetNArgs()+1; }
1858 virtual PyObject* GetCoVarNames() {
1859 PyObject* co_varnames = PyTuple_New( 1 + 1 );
1860 PyTuple_SET_ITEM( co_varnames, 0, PyROOT_PyUnicode_FromString(
"self" ) );
1861 PyTuple_SET_ITEM( co_varnames, 1, PyROOT_PyUnicode_FromString(
"*args" ) );
1864 virtual PyObject* GetArgDefault( Int_t ) {
return NULL; }
1866 Bool_t IsCallable( PyObject* pyobject )
1869 if ( ! pyobject || ! PyCallable_Check( pyobject ) ) {
1870 PyObject* str = pyobject ? PyObject_Str( pyobject ) : PyROOT_PyUnicode_FromString(
"null pointer" );
1871 PyErr_Format( PyExc_ValueError,
1872 "\"%s\" is not a valid python callable", PyROOT_PyUnicode_AsString( str ) );
1886 class TF1InitWithPyFunc :
public TPretendInterpreted {
1888 TF1InitWithPyFunc(
int ntf = 1 ) : TPretendInterpreted( 2 + 2*ntf ) {}
1891 virtual PyObject* GetSignature() {
return PyROOT_PyUnicode_FromString(
"(...)" ); }
1892 virtual PyObject* GetPrototype()
1894 return PyROOT_PyUnicode_FromString(
1895 "TF1::TF1(const char* name, PyObject* callable, "
1896 "Double_t xmin, Double_t xmax, Int_t npar = 0)" );
1898 virtual PyObject* GetScopeProxy() {
return CreateScopeProxy(
"TF1" ); }
1899 virtual PyCallable* Clone() {
return new TF1InitWithPyFunc( *
this ); }
1901 virtual PyObject* Call(
1902 ObjectProxy*&
self, PyObject* args, PyObject* , TCallContext* )
1905 int argc = PyTuple_GET_SIZE( args );
1906 const int reqNArgs = GetNArgs();
1907 if ( ! ( argc == reqNArgs || argc == reqNArgs+1 ) ) {
1908 PyErr_Format( PyExc_TypeError,
1909 "TFN::TFN(const char*, PyObject* callable, ...) =>\n"
1910 " takes at least %d and at most %d arguments (%d given)",
1911 reqNArgs, reqNArgs+1, argc );
1915 PyObject* pyfunc = PyTuple_GET_ITEM( args, 1 );
1919 if ( argc == reqNArgs+1 )
1920 npar = PyInt_AsLong( PyTuple_GET_ITEM( args, reqNArgs ) );
1923 std::vector<std::string> signature; signature.reserve( 2 );
1924 signature.push_back(
"double*" );
1925 signature.push_back(
"double*" );
1928 void* fptr = Utility::CreateWrapperMethod(
1929 pyfunc, npar,
"double", signature,
"TFNPyCallback" );
1934 MethodProxy* method =
1935 (MethodProxy*)PyObject_GetAttr( (PyObject*)
self, PyStrings::gInit );
1938 PyObject* newArgs = PyTuple_New( reqNArgs + 1 );
1940 for (
int iarg = 0; iarg < argc; ++iarg ) {
1941 PyObject* item = PyTuple_GET_ITEM( args, iarg );
1944 PyTuple_SET_ITEM( newArgs, iarg, item );
1946 PyTuple_SET_ITEM( newArgs, iarg, PyROOT_PyCapsule_New( fptr, NULL, NULL ) );
1950 if ( argc == reqNArgs )
1951 PyTuple_SET_ITEM( newArgs, reqNArgs, PyInt_FromLong( 0l ) );
1954 PyObject* result = PyObject_CallObject( (PyObject*)method, newArgs );
1957 Py_DECREF( newArgs );
1958 Py_DECREF( method );
1965 class TF2InitWithPyFunc :
public TF1InitWithPyFunc {
1967 TF2InitWithPyFunc() : TF1InitWithPyFunc( 2 ) {}
1970 virtual PyObject* GetPrototype()
1972 return PyROOT_PyUnicode_FromString(
1973 "TF2::TF2(const char* name, PyObject* callable, "
1974 "Double_t xmin, Double_t xmax, "
1975 "Double_t ymin, Double_t ymax, Int_t npar = 0)" );
1977 virtual PyObject* GetScopeProxy() {
return CreateScopeProxy(
"TF2" ); }
1978 virtual PyCallable* Clone() {
return new TF2InitWithPyFunc( *
this ); }
1983 class TF3InitWithPyFunc :
public TF1InitWithPyFunc {
1985 TF3InitWithPyFunc() : TF1InitWithPyFunc( 3 ) {}
1988 virtual PyObject* GetPrototype()
1990 return PyROOT_PyUnicode_FromString(
1991 "TF3::TF3(const char* name, PyObject* callable, "
1992 "Double_t xmin, Double_t xmax, "
1993 "Double_t ymin, Double_t ymax, "
1994 "Double_t zmin, Double_t zmax, Int_t npar = 0)" );
1996 virtual PyObject* GetScopeProxy() {
return CreateScopeProxy(
"TF3" ); }
1997 virtual PyCallable* Clone() {
return new TF3InitWithPyFunc( *
this ); }
2001 PyObject* TFunctionCall( ObjectProxy*&
self, PyObject* args ) {
2002 return TFunctionHolder( Cppyy::gGlobalScope, (Cppyy::TCppMethod_t)self->GetObject() ).Call(
self, args, 0 );
2007 class TMinuitSetFCN :
public TPretendInterpreted {
2009 TMinuitSetFCN(
int nArgs = 1 ) : TPretendInterpreted( nArgs ) {}
2012 virtual PyObject* GetSignature() {
return PyROOT_PyUnicode_FromString(
"(PyObject* callable)" ); }
2013 virtual PyObject* GetPrototype()
2015 return PyROOT_PyUnicode_FromString(
2016 "TMinuit::SetFCN(PyObject* callable)" );
2018 virtual PyObject* GetScopeProxy() {
return CreateScopeProxy(
"TMinuit" ); }
2019 virtual PyCallable* Clone() {
return new TMinuitSetFCN( *
this ); }
2021 virtual PyObject* Call(
2022 ObjectProxy*&
self, PyObject* args, PyObject* kwds, TCallContext* ctxt )
2025 int argc = PyTuple_GET_SIZE( args );
2027 PyErr_Format( PyExc_TypeError,
2028 "TMinuit::SetFCN(PyObject* callable, ...) =>\n"
2029 " takes exactly 1 argument (%d given)", argc );
2033 PyObject* pyfunc = PyTuple_GET_ITEM( args, 0 );
2034 if ( ! IsCallable( pyfunc ) )
2038 std::vector<std::string> signature; signature.reserve( 5 );
2039 signature.push_back(
"Int_t&" );
2040 signature.push_back(
"Double_t*" );
2041 signature.push_back(
"Double_t&" );
2042 signature.push_back(
"Double_t*" );
2043 signature.push_back(
"Int_t" );
2046 void* fptr = Utility::CreateWrapperMethod(
2047 pyfunc, 5,
"void", signature,
"TMinuitPyCallback" );
2052 MethodProxy* method =
2053 (MethodProxy*)PyObject_GetAttr( (PyObject*)
self, PyStrings::gSetFCN );
2058 PyCallable* setFCN = 0;
2059 const MethodProxy::Methods_t& methods = method->fMethodInfo->fMethods;
2060 for ( MethodProxy::Methods_t::const_iterator im = methods.begin(); im != methods.end(); ++im ) {
2061 PyObject* sig = (*im)->GetSignature();
2062 if ( sig && strstr( PyROOT_PyUnicode_AsString( sig ),
"Double_t&" ) ) {
2075 PyObject* newArgs = PyTuple_New( 1 );
2076 PyTuple_SET_ITEM( newArgs, 0, PyROOT_PyCapsule_New( fptr, NULL, NULL ) );
2081 PyObject* result = setFCN->Call(
self, newArgs, kwds, ctxt );
2085 Py_DECREF( newArgs );
2086 Py_DECREF( method );
2091 class TMinuitFitterSetFCN :
public TMinuitSetFCN {
2093 TMinuitFitterSetFCN() : TMinuitSetFCN( 1 ) {}
2096 virtual PyObject* GetPrototype()
2098 return PyROOT_PyUnicode_FromString(
2099 "TMinuitFitter::SetFCN(PyObject* callable)" );
2102 virtual PyCallable* Clone() {
return new TMinuitFitterSetFCN( *
this ); }
2104 virtual PyObject* Call(
2105 ObjectProxy*&
self, PyObject* args, PyObject* kwds, TCallContext* ctxt )
2108 int argc = PyTuple_GET_SIZE( args );
2110 PyErr_Format( PyExc_TypeError,
2111 "TMinuitFitter::SetFCN(PyObject* callable, ...) =>\n"
2112 " takes exactly 1 argument (%d given)", argc );
2116 return TMinuitSetFCN::Call(
self, args, kwds, ctxt );
2121 PyObject* gFitterPyCallback = 0;
2123 void FitterPyCallback(
int& npar,
double* gin,
double& f,
double* u,
int flag )
2126 PyObject* result = 0;
2129 PyObject* arg1 = BufFac_t::Instance()->PyBuffer_FromMemory( &npar );
2131 PyObject* arg2 = BufFac_t::Instance()->PyBuffer_FromMemory( gin );
2133 PyObject* arg3 = PyList_New( 1 );
2134 PyList_SetItem( arg3, 0, PyFloat_FromDouble( f ) );
2136 PyObject* arg4 = BufFac_t::Instance()->PyBuffer_FromMemory( u, npar *
sizeof(
double) );
2139 result = PyObject_CallFunction(
2140 gFitterPyCallback, (
char*)
"OOOOi", arg1, arg2, arg3, arg4, flag );
2141 f = PyFloat_AsDouble( PyList_GetItem( arg3, 0 ) );
2143 Py_DECREF( arg4 ); Py_DECREF( arg3 ); Py_DECREF( arg2 ); Py_DECREF( arg1 );
2147 throw std::runtime_error(
"TMinuit python fit function call failed" );
2150 Py_XDECREF( result );
2153 class TFitterFitFCN :
public TPretendInterpreted {
2155 TFitterFitFCN() : TPretendInterpreted( 2 ) {}
2158 virtual PyObject* GetSignature()
2160 return PyROOT_PyUnicode_FromString(
2161 "(PyObject* callable, int npar = 0, const double* params = 0, unsigned int dataSize = 0, bool chi2fit = false)" );
2163 virtual PyObject* GetPrototype()
2165 return PyROOT_PyUnicode_FromString(
2166 "TFitter::FitFCN(PyObject* callable, int npar = 0, const double* params = 0, unsigned int dataSize = 0, bool chi2fit = false)" );
2168 virtual PyObject* GetScopeProxy() {
return CreateScopeProxy(
"TFitter" ); }
2169 virtual PyCallable* Clone() {
return new TFitterFitFCN( *
this ); }
2171 virtual PyObject* Call(
2172 ObjectProxy*&
self, PyObject* args, PyObject* , TCallContext* )
2175 int argc = PyTuple_GET_SIZE( args );
2177 PyErr_Format( PyExc_TypeError,
2178 "TFitter::FitFCN(PyObject* callable, ...) =>\n"
2179 " takes at least 1 argument (%d given)", argc );
2183 PyObject* pyfunc = PyTuple_GET_ITEM( args, 0 );
2184 if ( ! IsCallable( pyfunc ) )
2188 Py_XDECREF( gFitterPyCallback );
2189 Py_INCREF( pyfunc );
2190 gFitterPyCallback = pyfunc;
2193 MethodProxy* method =
2194 (MethodProxy*)PyObject_GetAttr( (PyObject*)
self, PyStrings::gFitFCN );
2197 PyObject* newArgs = PyTuple_New( argc );
2198 PyTuple_SET_ITEM( newArgs, 0, PyROOT_PyCapsule_New( (
void*)FitterPyCallback, NULL, NULL ) );
2199 for (
int iarg = 1; iarg < argc; ++iarg ) {
2200 PyObject* pyarg = PyTuple_GET_ITEM( args, iarg );
2202 PyTuple_SET_ITEM( newArgs, iarg, pyarg );
2206 PyObject* result = PyObject_CallObject( (PyObject*)method, newArgs );
2209 Py_DECREF( newArgs );
2210 Py_DECREF( method );
2217 PyObject* TFileGetAttr( PyObject*
self, PyObject* attr )
2220 PyObject* result = CallPyObjMethod(
self,
"Get", attr );
2224 if ( !PyObject_IsTrue( result ) ) {
2225 PyObject* astr = PyObject_Str( attr );
2226 PyErr_Format( PyExc_AttributeError,
"TFile object has no attribute \'%s\'",
2227 PyROOT_PyUnicode_AsString( astr ) );
2229 Py_DECREF( result );
2235 PyObject_SetAttr(
self, attr, result );
2243 PyObject* TDirectoryFileGet( ObjectProxy*
self, PyObject* pynamecycle )
2246 if ( ! ObjectProxy_Check(
self ) ) {
2247 PyErr_SetString( PyExc_TypeError,
2248 "TDirectoryFile::Get must be called with a TDirectoryFile instance as first argument" );
2252 TDirectoryFile* dirf =
2253 (TDirectoryFile*)OP2TCLASS(
self)->DynamicCast( TDirectoryFile::Class(), self->GetObject() );
2255 PyErr_SetString( PyExc_ReferenceError,
"attempt to access a null-pointer" );
2259 const char* namecycle = PyROOT_PyUnicode_AsString( pynamecycle );
2263 TKey* key = dirf->GetKey( namecycle );
2265 void* addr = dirf->GetObjectChecked( namecycle, key->GetClassName() );
2266 return BindCppObjectNoCast( addr,
2267 (Cppyy::TCppType_t)Cppyy::GetScope( key->GetClassName() ), kFALSE );
2271 void* addr = dirf->Get( namecycle );
2272 return BindCppObject( addr, (Cppyy::TCppType_t)Cppyy::GetScope(
"TObject" ), kFALSE );
2276 PyObject *ClingPrintValue(ObjectProxy *
self)
2278 PyObject *cppname = PyObject_GetAttrString((PyObject *)
self,
"__cppname__");
2279 if (!PyROOT_PyUnicode_Check(cppname))
2281 std::string className = PyROOT_PyUnicode_AsString(cppname);
2282 Py_XDECREF(cppname);
2284 std::string printResult = gInterpreter->ToString(className.c_str(),
self->GetObject());
2285 if (printResult.find(
"@0x") == 0) {
2287 auto method = PyObject_GetAttrString((PyObject*)
self,
"__repr__");
2288 auto res = PyObject_CallObject(method,
nullptr);
2292 return PyROOT_PyUnicode_FromString(printResult.c_str());
2297 void AddArrayInterface(PyObject *pyclass, PyCFunction func)
2300 Utility::AddToClass(pyclass,
"_get__array_interface__", func, METH_NOARGS);
2306 if (!PyObject_HasAttrString(gRootModule,
"_add__array_interface__"))
return;
2308 auto f = PyObject_GetAttrString(gRootModule,
"_add__array_interface__");
2309 auto r = PyObject_CallFunction(f, (
char*)
"O", pyclass);
2314 template <
typename T,
char typestr>
2315 PyObject *ArrayInterface(ObjectProxy *
self)
2317 T *cobj =
reinterpret_cast<T*
>(
self->GetObject());
2320 auto dict = PyDict_New();
2323 auto pyversion = PyLong_FromLong(3);
2324 PyDict_SetItemString(dict,
"version", pyversion);
2325 Py_DECREF(pyversion);
2329 const char endianess =
'<';
2331 const char endianess =
'>';
2333 const UInt_t bytes =
sizeof(
typename T::value_type);
2334 auto pytypestr = PyROOT_PyUnicode_FromString(TString::Format(
"%c%c%i", endianess, typestr, bytes).Data());
2335 PyDict_SetItemString(dict,
"typestr", pytypestr);
2336 Py_DECREF(pytypestr);
2339 auto pysize = PyLong_FromLong(cobj->size());
2340 auto pyshape = PyTuple_Pack(1, pysize);
2341 PyDict_SetItemString(dict,
"shape", pyshape);
2346 auto ptr =
reinterpret_cast<unsigned long long>(cobj->data());
2349 if (cobj->empty()) ptr = 1;
2350 auto pyptr = PyLong_FromUnsignedLongLong(ptr);
2351 auto pydata = PyTuple_Pack(2, pyptr, Py_False);
2352 PyDict_SetItemString(dict,
"data", pydata);
2360 PyObject* ReturnThree( ObjectProxy*, PyObject* ) {
2361 return PyInt_FromLong( 3 );
2364 PyObject* ReturnTwo( ObjectProxy*, PyObject* ) {
2365 return PyInt_FromLong( 2 );
2372 Bool_t PyROOT::Pythonize( PyObject* pyclass,
const std::string& name )
2380 Utility::AddToClass(pyclass,
"__str__", (PyCFunction)ClingPrintValue);
2385 if ( HasAttrDirect( pyclass, PyStrings::gDeref ) ) {
2386 Utility::AddToClass( pyclass,
"__getattr__", (PyCFunction) DeRefGetAttr, METH_O );
2387 }
else if ( HasAttrDirect( pyclass, PyStrings::gFollow ) ) {
2388 Utility::AddToClass( pyclass,
"__getattr__", (PyCFunction) FollowGetAttr, METH_O );
2392 if ( HasAttrDirect( pyclass, PyStrings::gSize ) )
2393 Utility::AddToClass( pyclass,
"__len__",
"size" );
2396 if ( HasAttrDirect( pyclass, PyStrings::gGetSize ) )
2397 Utility::AddToClass( pyclass,
"__len__",
"GetSize" );
2399 if ( HasAttrDirect( pyclass, PyStrings::ggetSize ) )
2400 Utility::AddToClass( pyclass,
"__len__",
"getSize" );
2402 if ( HasAttrDirect( pyclass, PyStrings::gBegin ) && HasAttrDirect( pyclass, PyStrings::gEnd ) ) {
2404 PyObject* pyfullname = PyObject_GetAttr( pyclass, PyStrings::gCppName );
2405 if ( ! pyfullname ) pyfullname = PyObject_GetAttr( pyclass, PyStrings::gName );
2406 TClass* klass = TClass::GetClass( PyROOT_PyUnicode_AsString( pyfullname ) );
2407 Py_DECREF( pyfullname );
2409 if (!klass->InheritsFrom(TCollection::Class())) {
2419 TMethod* meth = klass->GetMethodAllAny(
"begin" );
2423 Int_t oldl = gErrorIgnoreLevel; gErrorIgnoreLevel = 3000;
2424 iklass = TClass::GetClass( meth->GetReturnTypeNormalizedName().c_str() );
2425 gErrorIgnoreLevel = oldl;
2428 if ( iklass && iklass->GetClassInfo() ) {
2429 ((PyTypeObject*)pyclass)->tp_iter = (getiterfunc)StlSequenceIter;
2430 Utility::AddToClass( pyclass,
"__iter__", (PyCFunction) StlSequenceIter, METH_NOARGS );
2431 }
else if ( HasAttrDirect( pyclass, PyStrings::gGetItem ) && HasAttrDirect( pyclass, PyStrings::gLen ) ) {
2432 Utility::AddToClass( pyclass,
"_getitem__unchecked",
"__getitem__" );
2433 Utility::AddToClass( pyclass,
"__getitem__", (PyCFunction) CheckedGetItem, METH_O );
2441 Utility::AddBinaryOperator( pyclass,
"==",
"__eq__" );
2442 Utility::AddBinaryOperator( pyclass,
"!=",
"__ne__" );
2447 if ( HasAttrDirect( pyclass, PyStrings::gEq, kTRUE ) ) {
2448 Utility::AddToClass( pyclass,
"__cpp_eq__",
"__eq__" );
2449 Utility::AddToClass( pyclass,
"__eq__", (PyCFunction) GenObjectIsEqual, METH_O );
2454 if ( HasAttrDirect( pyclass, PyStrings::gNe, kTRUE ) ) {
2455 Utility::AddToClass( pyclass,
"__cpp_ne__",
"__ne__" );
2456 Utility::AddToClass( pyclass,
"__ne__", (PyCFunction) GenObjectIsNotEqual, METH_O );
2462 if ( name ==
"TObject" ) {
2464 Utility::AddToClass( pyclass,
"__contains__", (PyCFunction) TObjectContains, METH_O );
2467 Utility::AddToClass( pyclass,
"__cmp__", (PyCFunction) TObjectCompare, METH_O );
2468 Utility::AddToClass( pyclass,
"__eq__", (PyCFunction) TObjectIsEqual, METH_O );
2469 Utility::AddToClass( pyclass,
"__ne__", (PyCFunction) TObjectIsNotEqual, METH_O );
2473 else if ( name ==
"TClass" ) {
2475 Utility::AddToClass( pyclass,
"_TClass__DynamicCast",
"DynamicCast" );
2476 Utility::AddToClass( pyclass,
"DynamicCast", (PyCFunction) TClassDynamicCast );
2479 Utility::AddToClass( pyclass,
"StaticCast", (PyCFunction) TClassStaticCast );
2483 else if ( name ==
"TCollection" ) {
2484 Utility::AddToClass( pyclass,
"append",
"Add" );
2485 Utility::AddToClass( pyclass,
"extend", (PyCFunction) TCollectionExtend, METH_O );
2486 Utility::AddToClass( pyclass,
"remove", (PyCFunction) TCollectionRemove, METH_O );
2487 Utility::AddToClass( pyclass,
"__add__", (PyCFunction) TCollectionAdd, METH_O );
2488 Utility::AddToClass( pyclass,
"__imul__", (PyCFunction) TCollectionIMul, METH_O );
2489 Utility::AddToClass( pyclass,
"__mul__", (PyCFunction) TCollectionMul, METH_O );
2490 Utility::AddToClass( pyclass,
"__rmul__", (PyCFunction) TCollectionMul, METH_O );
2492 Utility::AddToClass( pyclass,
"count", (PyCFunction) TCollectionCount, METH_O );
2494 ((PyTypeObject*)pyclass)->tp_iter = (getiterfunc)TCollectionIter;
2495 Utility::AddToClass( pyclass,
"__iter__", (PyCFunction)TCollectionIter, METH_NOARGS );
2499 else if ( name ==
"TSeqCollection" ) {
2500 Utility::AddToClass( pyclass,
"__getitem__", (PyCFunction) TSeqCollectionGetItem, METH_O );
2501 Utility::AddToClass( pyclass,
"__setitem__", (PyCFunction) TSeqCollectionSetItem );
2502 Utility::AddToClass( pyclass,
"__delitem__", (PyCFunction) TSeqCollectionDelItem, METH_O );
2504 Utility::AddToClass( pyclass,
"insert", (PyCFunction) TSeqCollectionInsert );
2505 Utility::AddToClass( pyclass,
"pop", (PyCFunction) TSeqCollectionPop );
2506 Utility::AddToClass( pyclass,
"reverse", (PyCFunction) TSeqCollectionReverse, METH_NOARGS );
2507 Utility::AddToClass( pyclass,
"sort", (PyCFunction) TSeqCollectionSort,
2508 METH_VARARGS | METH_KEYWORDS );
2510 Utility::AddToClass( pyclass,
"index", (PyCFunction) TSeqCollectionIndex, METH_O );
2514 else if ( name ==
"TObjArray" ) {
2515 Utility::AddToClass( pyclass,
"__len__", (PyCFunction) TObjArrayLen, METH_NOARGS );
2518 else if ( name ==
"TClonesArray" ) {
2522 Utility::AddToClass( pyclass,
"__getitem__", (PyCFunction) TSeqCollectionGetItem, METH_O );
2525 Utility::AddToClass( pyclass,
"__setitem__", (PyCFunction) TClonesArraySetItem );
2529 else if ( IsTemplatedSTLClass( name,
"vector" ) || (name.find(
"ROOT::VecOps::RVec<") == 0) ) {
2531 if ( HasAttrDirect( pyclass, PyStrings::gLen ) && HasAttrDirect( pyclass, PyStrings::gAt ) ) {
2532 Utility::AddToClass( pyclass,
"_vector__at",
"at" );
2534 if ( HasAttrDirect( pyclass, PyStrings::gIter ) )
2535 PyObject_DelAttr( pyclass, PyStrings::gIter );
2536 }
else if ( HasAttrDirect( pyclass, PyStrings::gGetItem ) ) {
2537 Utility::AddToClass( pyclass,
"_vector__at",
"__getitem__" );
2542 if ( name.find(
"vector<bool>") == std::string::npos && name.find(
"RVec<bool>") == std::string::npos ) {
2543 ((PyTypeObject*)pyclass)->tp_iter = (getiterfunc)vector_iter;
2547 TypedefInfo_t* ti = gInterpreter->TypedefInfo_Factory( (name+
"::value_type").c_str() );
2548 if ( gInterpreter->TypedefInfo_IsValid( ti ) ) {
2549 PyObject* pyvalue_size = PyLong_FromLong( gInterpreter->TypedefInfo_Size( ti ) );
2550 PyObject_SetAttrString( pyclass,
"value_size", pyvalue_size );
2551 Py_DECREF( pyvalue_size );
2553 PyObject* pyvalue_type = PyROOT_PyUnicode_FromString( gInterpreter->TypedefInfo_TrueName( ti ) );
2554 PyObject_SetAttrString( pyclass,
"value_type", pyvalue_type );
2555 Py_DECREF( pyvalue_type );
2557 gInterpreter->TypedefInfo_Delete( ti );
2560 if ( HasAttrDirect( pyclass, PyStrings::gVectorAt ) )
2561 Utility::AddToClass( pyclass,
"__getitem__", (PyCFunction) VectorGetItem, METH_O );
2564 std::string::size_type pos = name.find(
"vector<bool" );
2565 if ( pos == 0 || pos == 5 ) {
2566 Utility::AddToClass( pyclass,
"__setitem__", (PyCFunction) VectorBoolSetItem );
2570 if (name.find(
"ROOT::VecOps::RVec<") == 0) {
2571 }
else if (name ==
"vector<float>") {
2572 AddArrayInterface(pyclass, (PyCFunction)ArrayInterface<std::vector<float>,
'f'>);
2573 }
else if (name ==
"vector<double>") {
2574 AddArrayInterface(pyclass, (PyCFunction)ArrayInterface<std::vector<double>,
'f'>);
2575 }
else if (name ==
"vector<int>") {
2576 AddArrayInterface(pyclass, (PyCFunction)ArrayInterface<std::vector<int>,
'i'>);
2577 }
else if (name ==
"vector<unsigned int>") {
2578 AddArrayInterface(pyclass, (PyCFunction)ArrayInterface<std::vector<unsigned int>,
'u'>);
2579 }
else if (name ==
"vector<long>") {
2580 AddArrayInterface(pyclass, (PyCFunction)ArrayInterface<std::vector<long>,
'i'>);
2581 }
else if (name ==
"vector<unsigned long>") {
2582 AddArrayInterface(pyclass, (PyCFunction)ArrayInterface<std::vector<unsigned long>,
'u'>);
2586 if (name.find(
"ROOT::VecOps::RVec<") != 0) {
2587 }
else if (name ==
"ROOT::VecOps::RVec<float>") {
2588 AddArrayInterface(pyclass, (PyCFunction)ArrayInterface<ROOT::VecOps::RVec<float>,
'f'>);
2589 }
else if (name ==
"ROOT::VecOps::RVec<double>") {
2590 AddArrayInterface(pyclass, (PyCFunction)ArrayInterface<ROOT::VecOps::RVec<double>,
'f'>);
2591 }
else if (name ==
"ROOT::VecOps::RVec<int>") {
2592 AddArrayInterface(pyclass, (PyCFunction)ArrayInterface<ROOT::VecOps::RVec<int>,
'i'>);
2593 }
else if (name ==
"ROOT::VecOps::RVec<unsigned int>") {
2594 AddArrayInterface(pyclass, (PyCFunction)ArrayInterface<ROOT::VecOps::RVec<unsigned int>,
'u'>);
2595 }
else if (name ==
"ROOT::VecOps::RVec<long>") {
2596 AddArrayInterface(pyclass, (PyCFunction)ArrayInterface<ROOT::VecOps::RVec<long>,
'i'>);
2597 }
else if (name ==
"ROOT::VecOps::RVec<unsigned long>") {
2598 AddArrayInterface(pyclass, (PyCFunction)ArrayInterface<ROOT::VecOps::RVec<unsigned long>,
'u'>);
2602 else if ( IsTemplatedSTLClass( name,
"map" ) ) {
2603 Utility::AddToClass( pyclass,
"__contains__", (PyCFunction) MapContains, METH_O );
2607 else if ( IsTemplatedSTLClass( name,
"pair" ) ) {
2608 Utility::AddToClass( pyclass,
"__getitem__", (PyCFunction) PairUnpack, METH_O );
2609 Utility::AddToClass( pyclass,
"__len__", (PyCFunction) ReturnTwo, METH_NOARGS );
2613 else if ( name.find(
"iterator" ) != std::string::npos ) {
2614 ((PyTypeObject*)pyclass)->tp_iternext = (iternextfunc)StlIterNext;
2615 Utility::AddToClass( pyclass, PYROOT__next__, (PyCFunction) StlIterNext, METH_NOARGS );
2618 if ( ! HasAttrDirect( pyclass, PyStrings::gCppEq, kTRUE ) )
2619 Utility::AddToClass( pyclass,
"__eq__", (PyCFunction) StlIterIsEqual, METH_O );
2620 if ( ! HasAttrDirect( pyclass, PyStrings::gCppNe, kTRUE ) )
2621 Utility::AddToClass( pyclass,
"__ne__", (PyCFunction) StlIterIsNotEqual, METH_O );
2625 else if ( name ==
"string" || name ==
"std::string" ) {
2626 Utility::AddToClass( pyclass,
"__repr__", (PyCFunction) StlStringRepr, METH_NOARGS );
2627 Utility::AddToClass( pyclass,
"__str__",
"c_str" );
2628 Utility::AddToClass( pyclass,
"__cmp__", (PyCFunction) StlStringCompare, METH_O );
2629 Utility::AddToClass( pyclass,
"__eq__", (PyCFunction) StlStringIsEqual, METH_O );
2630 Utility::AddToClass( pyclass,
"__ne__", (PyCFunction) StlStringIsNotEqual, METH_O );
2634 else if ( name ==
"TString" ) {
2635 Utility::AddToClass( pyclass,
"__repr__", (PyCFunction) TStringRepr, METH_NOARGS );
2636 Utility::AddToClass( pyclass,
"__str__",
"Data" );
2637 Utility::AddToClass( pyclass,
"__len__",
"Length" );
2639 Utility::AddToClass( pyclass,
"__cmp__",
"CompareTo" );
2640 Utility::AddToClass( pyclass,
"__eq__", (PyCFunction) TStringIsEqual, METH_O );
2641 Utility::AddToClass( pyclass,
"__ne__", (PyCFunction) TStringIsNotEqual, METH_O );
2645 else if ( name ==
"TObjString" ) {
2646 Utility::AddToClass( pyclass,
"__repr__", (PyCFunction) TObjStringRepr, METH_NOARGS );
2647 Utility::AddToClass( pyclass,
"__str__",
"GetName" );
2648 Utility::AddToClass( pyclass,
"__len__", (PyCFunction) TObjStringLength, METH_NOARGS );
2650 Utility::AddToClass( pyclass,
"__cmp__", (PyCFunction) TObjStringCompare, METH_O );
2651 Utility::AddToClass( pyclass,
"__eq__", (PyCFunction) TObjStringIsEqual, METH_O );
2652 Utility::AddToClass( pyclass,
"__ne__", (PyCFunction) TObjStringIsNotEqual, METH_O );
2656 else if ( name ==
"TIter" ) {
2657 ((PyTypeObject*)pyclass)->tp_iter = (getiterfunc)PyObject_SelfIter;
2658 Utility::AddToClass( pyclass,
"__iter__", (PyCFunction) PyObject_SelfIter, METH_NOARGS );
2660 ((PyTypeObject*)pyclass)->tp_iternext = (iternextfunc)TIterNext;
2661 Utility::AddToClass( pyclass, PYROOT__next__, (PyCFunction) TIterNext, METH_NOARGS );
2665 else if ( name ==
"TDirectory" ) {
2667 Utility::AddToClass( pyclass,
"GetObject", (PyCFunction) TDirectoryGetObject );
2670 Utility::AddToClass( pyclass,
"WriteObject", (PyCFunction) TDirectoryWriteObject );
2674 else if ( name ==
"TDirectoryFile" ) {
2676 Utility::AddToClass( pyclass,
"Get", (PyCFunction) TDirectoryFileGet, METH_O );
2679 Utility::AddToClass(pyclass,
"GetObject", (PyCFunction)TDirectoryGetObject);
2684 else if ( name ==
"TTree" ) {
2686 Utility::AddToClass( pyclass,
"__getattr__", (PyCFunction) TTreeGetAttr, METH_O );
2689 MethodProxy* original =
2690 (MethodProxy*)PyObject_GetAttrFromDict( pyclass, PyStrings::gBranch );
2691 MethodProxy* method = MethodProxy_New(
"Branch",
new TTreeBranch( original ) );
2692 Py_DECREF( original ); original = 0;
2694 PyObject_SetAttrString(
2695 pyclass, const_cast< char* >( method->GetName().c_str() ), (PyObject*)method );
2696 Py_DECREF( method ); method = 0;
2699 original = (MethodProxy*)PyObject_GetAttrFromDict( pyclass, PyStrings::gSetBranchAddress );
2700 method = MethodProxy_New( "SetBranchAddress", new TTreeSetBranchAddress( original ) );
2701 Py_DECREF( original ); original = 0;
2703 PyObject_SetAttrString(
2704 pyclass, const_cast<
char* >( method->GetName().c_str() ), (PyObject*)method );
2705 Py_DECREF( method ); method = 0;
2709 else if ( name == "TChain" ) {
2711 MethodProxy* original =
2712 (MethodProxy*)PyObject_GetAttrFromDict( pyclass, PyStrings::gSetBranchAddress );
2713 MethodProxy* method = MethodProxy_New(
"SetBranchAddress",
new TChainSetBranchAddress( original ) );
2714 Py_DECREF( original ); original = 0;
2716 PyObject_SetAttrString(
2717 pyclass, const_cast< char* >( method->GetName().c_str() ), (PyObject*)method );
2718 Py_DECREF( method ); method = 0;
2722 else if ( name.find("ROOT::RDataFrame") == 0 || name.find("ROOT::RDF::RInterface<") == 0 ) {
2723 if (PyObject_HasAttrString( gRootModule,
"_RDataFrameAsNumpy" )) {
2724 PyObject_SetAttrString(pyclass,
"AsNumpy",
2725 PyObject_GetAttrString( gRootModule,
"_RDataFrameAsNumpy" ));
2729 else if ( name ==
"TStyle" ) {
2730 MethodProxy* ctor = (MethodProxy*)PyObject_GetAttr( pyclass, PyStrings::gInit );
2731 ctor->fMethodInfo->fFlags &= ~TCallContext::kIsCreator;
2735 else if ( name ==
"TH1" )
2736 Utility::AddToClass( pyclass,
"__imul__", (PyCFunction) THNIMul, METH_O );
2738 else if ( name ==
"TF1" )
2739 Utility::AddToClass( pyclass,
"__init__",
new TF1InitWithPyFunc );
2741 else if ( name ==
"TF2" )
2742 Utility::AddToClass( pyclass,
"__init__",
new TF2InitWithPyFunc );
2744 else if ( name ==
"TF3" )
2745 Utility::AddToClass( pyclass,
"__init__",
new TF3InitWithPyFunc );
2747 else if ( name ==
"TFunction" )
2748 Utility::AddToClass( pyclass,
"__call__", (PyCFunction) TFunctionCall );
2750 else if ( name ==
"TMinuit" )
2751 Utility::AddToClass( pyclass,
"SetFCN",
new TMinuitSetFCN );
2753 else if ( name ==
"TFitter" )
2754 Utility::AddToClass( pyclass,
"SetFCN",
new TMinuitFitterSetFCN );
2756 else if ( name ==
"Fitter" )
2757 Utility::AddToClass( pyclass,
"FitFCN",
new TFitterFitFCN );
2759 else if ( name ==
"TFile" ) {
2761 PyObject* attr = PyObject_GetAttrString( pyclass, (
char*)
"Open" );
2762 if ( MethodProxy_Check( attr ) )
2763 ((MethodProxy*)attr)->fMethodInfo->fFlags |= TCallContext::kIsCreator;
2767 Utility::AddToClass( pyclass,
"__getattr__", (PyCFunction) TFileGetAttr, METH_O );
2770 else if ( name.substr(0,8) ==
"TVector3" ) {
2771 Utility::AddToClass( pyclass,
"__len__", (PyCFunction) ReturnThree, METH_NOARGS );
2772 Utility::AddToClass( pyclass,
"_getitem__unchecked",
"__getitem__" );
2773 Utility::AddToClass( pyclass,
"__getitem__", (PyCFunction) CheckedGetItem, METH_O );
2777 else if ( name.substr(0,8) ==
"TVectorT" ) {
2779 Utility::AddToClass( pyclass,
"__len__",
"GetNoElements" );
2780 Utility::AddToClass( pyclass,
"_getitem__unchecked",
"__getitem__" );
2781 Utility::AddToClass( pyclass,
"__getitem__", (PyCFunction) CheckedGetItem, METH_O );
2784 else if ( name.substr(0,6) ==
"TArray" && name !=
"TArray" ) {
2786 Utility::AddToClass( pyclass,
"_getitem__unchecked",
"__getitem__" );
2787 Utility::AddToClass( pyclass,
"__getitem__", (PyCFunction) CheckedGetItem, METH_O );
2791 else if ( name ==
"RooDataHist" )
2792 Utility::AddUsingToClass( pyclass,
"plotOn" );
2794 else if ( name ==
"RooSimultaneous" )
2795 Utility::AddUsingToClass( pyclass,
"plotOn" );
2799 PyObject* userPythonizations = PyObject_GetAttrString( gRootModule,
"UserPythonizations" );
2800 PyObject* pythonizationScope = PyObject_GetAttrString( gRootModule,
"PythonizationScope" );
2802 std::vector< std::string > pythonization_scopes;
2803 pythonization_scopes.push_back(
"__global__" );
2805 std::string user_scope = PyROOT_PyUnicode_AsString( pythonizationScope );
2806 if ( user_scope !=
"__global__" ) {
2807 if ( PyDict_Contains( userPythonizations, pythonizationScope ) ) {
2808 pythonization_scopes.push_back( user_scope );
2812 Bool_t pstatus = kTRUE;
2814 for (
auto key = pythonization_scopes.cbegin(); key != pythonization_scopes.cend(); ++key ) {
2815 PyObject* tmp = PyDict_GetItemString( userPythonizations, key->c_str() );
2816 Py_ssize_t num_pythonizations = PyList_Size( tmp );
2817 PyObject* arglist =
nullptr;
2818 if ( num_pythonizations )
2819 arglist = Py_BuildValue(
"O,s", pyclass, name.c_str() );
2820 for ( Py_ssize_t i = 0; i < num_pythonizations; ++i ) {
2821 PyObject* pythonizor = PyList_GetItem( tmp, i );
2823 PyObject* result = PyObject_CallObject( pythonizor, arglist );
2828 Py_DECREF( result );
2830 Py_XDECREF( arglist );
2833 Py_DECREF( userPythonizations );
2834 Py_DECREF( pythonizationScope );