ROOT  6.07/01
Reference Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Pythonize.cxx
Go to the documentation of this file.
1 // @(#)root/pyroot:$Id$
2 // Author: Wim Lavrijsen, Jul 2004
3 
4 // Bindings
5 #include "PyROOT.h"
6 #include "PyStrings.h"
7 #include "Pythonize.h"
8 #include "ObjectProxy.h"
9 #include "MethodProxy.h"
10 #include "RootWrapper.h"
11 #include "Utility.h"
12 #include "PyCallable.h"
13 #include "TPyBufferFactory.h"
14 #include "TFunctionHolder.h"
15 #include "Converters.h"
16 #include "TMemoryRegulator.h"
17 #include "Utility.h"
18 
19 // ROOT
20 #include "TClass.h"
21 #include "TFunction.h"
22 #include "TInterpreter.h"
23 #include "TMethod.h"
24 
25 #include "TClonesArray.h"
26 #include "TCollection.h"
27 #include "TDirectory.h"
28 #include "TError.h"
29 #include "TFile.h"
30 #include "TKey.h"
31 #include "TObject.h"
32 #include "TObjArray.h"
33 #include "TSeqCollection.h"
34 
35 #include "TTree.h"
36 #include "TBranch.h"
37 #include "TBranchElement.h"
38 #include "TBranchObject.h"
39 #include "TLeaf.h"
40 #include "TLeafElement.h"
41 #include "TLeafObject.h"
42 #include "TStreamerElement.h"
43 #include "TStreamerInfo.h"
44 
45 // Standard
46 #include <stdexcept>
47 #include <string>
48 #include <utility>
49 
50 #include <stdio.h>
51 #include <string.h> // only needed for Cling TMinuit workaround
52 
53 
54 // temp (?)
55 static inline TClass* OP2TCLASS( PyROOT::ObjectProxy* pyobj ) {
56  return TClass::GetClass( Cppyy::GetFinalName( pyobj->ObjectIsA() ).c_str());
57 }
58 //-- temp
59 
60 //- data and local helpers ---------------------------------------------------
61 namespace PyROOT {
63 }
64 
65 namespace {
66 
67 // for convenience
68  using namespace PyROOT;
69 
70 ////////////////////////////////////////////////////////////////////////////////
71 /// prevents calls to Py_TYPE(pyclass)->tp_getattr, which is unnecessary for our
72 /// purposes here and could tickle problems w/ spurious lookups into ROOT meta
73 
74  Bool_t HasAttrDirect( PyObject* pyclass, PyObject* pyname, Bool_t mustBePyROOT = kFALSE ) {
75  PyObject* attr = PyType_Type.tp_getattro( pyclass, pyname );
76  if ( attr != 0 && ( ! mustBePyROOT || MethodProxy_Check( attr ) ) ) {
77  Py_DECREF( attr );
78  return kTRUE;
79  }
80 
81  PyErr_Clear();
82  return kFALSE;
83  }
84 
85 ////////////////////////////////////////////////////////////////////////////////
86 /// prevents calls to descriptors
87 
88  PyObject* PyObject_GetAttrFromDict( PyObject* pyclass, PyObject* pyname ) {
89  PyObject* dict = PyObject_GetAttr( pyclass, PyStrings::gDict );
90  PyObject* attr = PyObject_GetItem( dict, pyname );
91  Py_DECREF( dict );
92  return attr;
93  }
94 
95 ////////////////////////////////////////////////////////////////////////////////
96 /// Scan the name of the class and determine whether it is a template instantiation.
97 
98  inline Bool_t IsTemplatedSTLClass( const std::string& name, const std::string& klass ) {
99  const int nsize = (int)name.size();
100  const int ksize = (int)klass.size();
101 
102  return ( ( ksize < nsize && name.substr(0,ksize) == klass ) ||
103  ( ksize+5 < nsize && name.substr(5,ksize) == klass ) ) &&
104  name.find( "::", name.find( ">" ) ) == std::string::npos;
105  }
106 
107 // to prevent compiler warnings about const char* -> char*
108  inline PyObject* CallPyObjMethod( PyObject* obj, const char* meth )
109  {
110  // Helper; call method with signature: obj->meth().
111  Py_INCREF( obj );
112  PyObject* result = PyObject_CallMethod( obj, const_cast< char* >( meth ), const_cast< char* >( "" ) );
113  Py_DECREF( obj );
114  return result;
115  }
116 
117 ////////////////////////////////////////////////////////////////////////////////
118 /// Helper; call method with signature: obj->meth( arg1 ).
119 
120  inline PyObject* CallPyObjMethod( PyObject* obj, const char* meth, PyObject* arg1 )
121  {
122  Py_INCREF( obj );
123  PyObject* result = PyObject_CallMethod(
124  obj, const_cast< char* >( meth ), const_cast< char* >( "O" ), arg1 );
125  Py_DECREF( obj );
126  return result;
127  }
128 
129 ////////////////////////////////////////////////////////////////////////////////
130 /// Helper; call method with signature: obj->meth( arg1, arg2 ).
131 
132  inline PyObject* CallPyObjMethod(
133  PyObject* obj, const char* meth, PyObject* arg1, PyObject* arg2 )
134  {
135  Py_INCREF( obj );
136  PyObject* result = PyObject_CallMethod(
137  obj, const_cast< char* >( meth ), const_cast< char* >( "OO" ), arg1, arg2 );
138  Py_DECREF( obj );
139  return result;
140  }
141 
142 ////////////////////////////////////////////////////////////////////////////////
143 /// Helper; call method with signature: obj->meth( arg1, int ).
144 
145  inline PyObject* CallPyObjMethod( PyObject* obj, const char* meth, PyObject* arg1, int arg2 )
146  {
147  Py_INCREF( obj );
148  PyObject* result = PyObject_CallMethod(
149  obj, const_cast< char* >( meth ), const_cast< char* >( "Oi" ), arg1, arg2 );
150  Py_DECREF( obj );
151  return result;
152  }
153 
154 
155 //- helpers --------------------------------------------------------------------
156  PyObject* PyStyleIndex( PyObject* self, PyObject* index )
157  {
158  // Helper; converts python index into straight C index.
159  Py_ssize_t idx = PyInt_AsSsize_t( index );
160  if ( idx == (Py_ssize_t)-1 && PyErr_Occurred() )
161  return 0;
162 
163  Py_ssize_t size = PySequence_Size( self );
164  if ( idx >= size || ( idx < 0 && idx < -size ) ) {
165  PyErr_SetString( PyExc_IndexError, "index out of range" );
166  return 0;
167  }
168 
169  PyObject* pyindex = 0;
170  if ( idx >= 0 ) {
171  Py_INCREF( index );
172  pyindex = index;
173  } else
174  pyindex = PyLong_FromLong( size + idx );
175 
176  return pyindex;
177  }
178 
179 ////////////////////////////////////////////////////////////////////////////////
180 /// Helper; call method with signature: meth( pyindex ).
181 
182  inline PyObject* CallSelfIndex( ObjectProxy* self, PyObject* idx, const char* meth )
183  {
184  Py_INCREF( (PyObject*)self );
185  PyObject* pyindex = PyStyleIndex( (PyObject*)self, idx );
186  if ( ! pyindex ) {
187  Py_DECREF( (PyObject*)self );
188  return 0;
189  }
190 
191  PyObject* result = CallPyObjMethod( (PyObject*)self, meth, pyindex );
192  Py_DECREF( pyindex );
193  Py_DECREF( (PyObject*)self );
194  return result;
195  }
196 
197 ////////////////////////////////////////////////////////////////////////////////
198 /// Helper; convert generic python object into a boolean value.
199 
200  inline PyObject* BoolNot( PyObject* value )
201  {
202  if ( PyObject_IsTrue( value ) == 1 ) {
203  Py_INCREF( Py_False );
204  Py_DECREF( value );
205  return Py_False;
206  } else {
207  Py_INCREF( Py_True );
208  Py_XDECREF( value );
209  return Py_True;
210  }
211  }
212 
213 //- "smart pointer" behavior ---------------------------------------------------
214  PyObject* DeRefGetAttr( PyObject* self, PyObject* name )
215  {
216  // Follow operator*() if present (available in python as __deref__), so that
217  // smart pointers behave as expected.
218  if ( ! PyROOT_PyUnicode_Check( name ) )
219  PyErr_SetString( PyExc_TypeError, "getattr(): attribute name must be string" );
220 
221  PyObject* pyptr = CallPyObjMethod( self, "__deref__" );
222  if ( ! pyptr )
223  return 0;
224 
225  // prevent a potential infinite loop
226  if ( Py_TYPE(pyptr) == Py_TYPE(self) ) {
227  PyObject* val1 = PyObject_Str( self );
228  PyObject* val2 = PyObject_Str( name );
229  PyErr_Format( PyExc_AttributeError, "%s has no attribute \'%s\'",
231  Py_DECREF( val2 );
232  Py_DECREF( val1 );
233 
234  Py_DECREF( pyptr );
235  return 0;
236  }
237 
238  PyObject* result = PyObject_GetAttr( pyptr, name );
239  Py_DECREF( pyptr );
240  return result;
241  }
242 
243 ////////////////////////////////////////////////////////////////////////////////
244 /// Follow operator->() if present (available in python as __follow__), so that
245 /// smart pointers behave as expected.
246 
247  PyObject* FollowGetAttr( PyObject* self, PyObject* name )
248  {
249  if ( ! PyROOT_PyUnicode_Check( name ) )
250  PyErr_SetString( PyExc_TypeError, "getattr(): attribute name must be string" );
251 
252  PyObject* pyptr = CallPyObjMethod( self, "__follow__" );
253  if ( ! pyptr )
254  return 0;
255 
256  PyObject* result = PyObject_GetAttr( pyptr, name );
257  Py_DECREF( pyptr );
258  return result;
259  }
260 
261 //- TObject behavior -----------------------------------------------------------
262  PyObject* TObjectContains( PyObject* self, PyObject* obj )
263  {
264  // Implement python's __contains__ with TObject::FindObject.
265  if ( ! ( ObjectProxy_Check( obj ) || PyROOT_PyUnicode_Check( obj ) ) )
266  return PyInt_FromLong( 0l );
267 
268  PyObject* found = CallPyObjMethod( self, "FindObject", obj );
269  PyObject* result = PyInt_FromLong( PyObject_IsTrue( found ) );
270  Py_DECREF( found );
271  return result;
272  }
273 
274 ////////////////////////////////////////////////////////////////////////////////
275 /// Implement python's __cmp__ with TObject::Compare.
276 
277  PyObject* TObjectCompare( PyObject* self, PyObject* obj )
278  {
279  if ( ! ObjectProxy_Check( obj ) )
280  return PyInt_FromLong( -1l );
281 
282  return CallPyObjMethod( self, "Compare", obj );
283  }
284 
285 ////////////////////////////////////////////////////////////////////////////////
286 /// Implement python's __eq__ with TObject::IsEqual.
287 
288  PyObject* TObjectIsEqual( PyObject* self, PyObject* obj )
289  {
290  if ( ! ObjectProxy_Check( obj ) || ! ((ObjectProxy*)obj)->fObject )
291  return ObjectProxy_Type.tp_richcompare( self, obj, Py_EQ );
292 
293  return CallPyObjMethod( self, "IsEqual", obj );
294  }
295 
296 ////////////////////////////////////////////////////////////////////////////////
297 /// Implement python's __ne__ in terms of not TObject::IsEqual.
298 
299  PyObject* TObjectIsNotEqual( PyObject* self, PyObject* obj )
300  {
301  if ( ! ObjectProxy_Check( obj ) || ! ((ObjectProxy*)obj)->fObject )
302  return ObjectProxy_Type.tp_richcompare( self, obj, Py_NE );
303 
304  return BoolNot( CallPyObjMethod( self, "IsEqual", obj ) );
305  }
306 
307 ////////////////////////////////////////////////////////////////////////////////
308 /// Contrary to TObjectIsEqual, it can now not be relied upon that the only
309 /// non-ObjectProxy obj is None, as any operator==(), taking any object (e.g.
310 /// an enum) can be implemented. However, those cases will yield an exception
311 /// if presented with None.
312 
313  PyObject* GenObjectIsEqual( PyObject* self, PyObject* obj )
314  {
315  PyObject* result = CallPyObjMethod( self, "__cpp_eq__", obj );
316  if ( ! result ) {
317  PyErr_Clear();
318  result = ObjectProxy_Type.tp_richcompare( self, obj, Py_EQ );
319  }
320 
321  return result;
322  }
323 
324 ////////////////////////////////////////////////////////////////////////////////
325 /// Reverse of GenObjectIsEqual, if operator!= defined.
326 
327  PyObject* GenObjectIsNotEqual( PyObject* self, PyObject* obj )
328  {
329  PyObject* result = CallPyObjMethod( self, "__cpp_ne__", obj );
330  if ( ! result ) {
331  PyErr_Clear();
332  result = ObjectProxy_Type.tp_richcompare( self, obj, Py_NE );
333  }
334 
335  return result;
336  }
337 
338 //- TClass behavior ------------------------------------------------------------
339  PyObject* TClassStaticCast( ObjectProxy* self, PyObject* args )
340  {
341  // Implemented somewhat different than TClass::DynamicClass, in that "up" is
342  // chosen automatically based on the relationship between self and arg pyclass.
343  ObjectProxy* pyclass = 0; PyObject* pyobject = 0;
344  if ( ! PyArg_ParseTuple( args, const_cast< char* >( "O!O:StaticCast" ),
345  &ObjectProxy_Type, &pyclass, &pyobject ) )
346  return 0;
347 
348  // check the given arguments (dcasts are necessary b/c of could be a TQClass
349  TClass* from = (TClass*)OP2TCLASS(self)->DynamicCast( TClass::Class(), self->GetObject() );
350  TClass* to = (TClass*)OP2TCLASS(self)->DynamicCast( TClass::Class(), pyclass->GetObject() );
351 
352  if ( ! from ) {
353  PyErr_SetString( PyExc_TypeError, "unbound method TClass::StaticCast "
354  "must be called with a TClass instance as first argument" );
355  return 0;
356  }
357 
358  if ( ! to ) {
359  PyErr_SetString( PyExc_TypeError, "could not convert argument 1 (TClass* expected)" );
360  return 0;
361  }
362 
363  // retrieve object address
364  void* address = 0;
365  if ( ObjectProxy_Check( pyobject ) ) address = ((ObjectProxy*)pyobject)->GetObject();
366  else if ( PyInt_Check( pyobject ) || PyLong_Check( pyobject ) ) address = (void*)PyLong_AsLong( pyobject );
367  else Utility::GetBuffer( pyobject, '*', 1, address, kFALSE );
368 
369  if ( ! address ) {
370  PyErr_SetString( PyExc_TypeError, "could not convert argument 2 (void* expected)" );
371  return 0;
372  }
373 
374  // determine direction of cast
375  int up = -1;
376  if ( from->InheritsFrom( to ) ) up = 1;
377  else if ( to->InheritsFrom( from ) ) {
378  TClass* tmp = to; to = from; from = tmp;
379  up = 0;
380  }
381 
382  if ( up == -1 ) {
383  PyErr_Format( PyExc_TypeError, "unable to cast %s to %s", from->GetName(), to->GetName() );
384  return 0;
385  }
386 
387  // perform actual cast
388  void* result = from->DynamicCast( to, address, (Bool_t)up );
389 
390  // at this point, "result" can't be null (but is still safe if it is)
391  return BindCppObjectNoCast( result, Cppyy::GetScope( to->GetName() ) );
392  }
393 
394 ////////////////////////////////////////////////////////////////////////////////
395 /// TClass::DynamicCast returns a void* that the user still has to cast (it
396 /// will have the proper offset, though). Fix this by providing the requested
397 /// binding if the cast succeeded.
398 
399  PyObject* TClassDynamicCast( ObjectProxy* self, PyObject* args )
400  {
401  ObjectProxy* pyclass = 0; PyObject* pyobject = 0;
402  Long_t up = 1;
403  if ( ! PyArg_ParseTuple( args, const_cast< char* >( "O!O|l:DynamicCast" ),
404  &ObjectProxy_Type, &pyclass, &pyobject, &up ) )
405  return 0;
406 
407  // perform actual cast
408  PyObject* meth = PyObject_GetAttr( (PyObject*)self, PyStrings::gTClassDynCast );
409  PyObject* ptr = meth ? PyObject_Call( meth, args, 0 ) : 0;
410  Py_XDECREF( meth );
411 
412  // simply forward in case of call failure
413  if ( ! ptr )
414  return ptr;
415 
416  // retrieve object address
417  void* address = 0;
418  if ( ObjectProxy_Check( pyobject ) ) address = ((ObjectProxy*)pyobject)->GetObject();
419  else if ( PyInt_Check( pyobject ) || PyLong_Check( pyobject ) ) address = (void*)PyLong_AsLong( pyobject );
420  else Utility::GetBuffer( pyobject, '*', 1, address, kFALSE );
421 
422  if ( PyErr_Occurred() ) {
423  PyErr_Clear();
424  return ptr;
425  }
426 
427  // now use binding to return a usable class
428  TClass* klass = 0;
429  if ( up ) { // up-cast: result is a base
430  klass = (TClass*)OP2TCLASS(pyclass)->DynamicCast( TClass::Class(), pyclass->GetObject() );
431  } else { // down-cast: result is a derived
432  klass = (TClass*)OP2TCLASS(self)->DynamicCast( TClass::Class(), self->GetObject() );
433  }
434 
435  PyObject* result = BindCppObjectNoCast( (void*)address, Cppyy::GetScope( klass->GetName() ) );
436  Py_DECREF( ptr );
437 
438  return result;
439  }
440 
441 //- TCollection behavior -------------------------------------------------------
442  PyObject* TCollectionExtend( PyObject* self, PyObject* obj )
443  {
444  // Implement a python-style extend with TCollection::Add.
445  for ( Py_ssize_t i = 0; i < PySequence_Size( obj ); ++i ) {
446  PyObject* item = PySequence_GetItem( obj, i );
447  PyObject* result = CallPyObjMethod( self, "Add", item );
448  Py_XDECREF( result );
449  Py_DECREF( item );
450  }
451 
452  Py_INCREF( Py_None );
453  return Py_None;
454  }
455 
456 ////////////////////////////////////////////////////////////////////////////////
457 /// Implement a python-style remove with TCollection::Add.
458 
459  PyObject* TCollectionRemove( PyObject* self, PyObject* obj )
460  {
461  PyObject* result = CallPyObjMethod( self, "Remove", obj );
462  if ( ! result )
463  return 0;
464 
465  if ( ! PyObject_IsTrue( result ) ) {
466  Py_DECREF( result );
467  PyErr_SetString( PyExc_ValueError, "list.remove(x): x not in list" );
468  return 0;
469  }
470 
471  Py_DECREF( result );
472  Py_INCREF( Py_None );
473  return Py_None;
474  }
475 
476 ////////////////////////////////////////////////////////////////////////////////
477 /// Implement python's __add__ with the pythonized extend for TCollections.
478 
479  PyObject* TCollectionAdd( PyObject* self, PyObject* other )
480  {
481  PyObject* l = CallPyObjMethod( self, "Clone" );
482  if ( ! l )
483  return 0;
484 
485  PyObject* result = CallPyObjMethod( l, "extend", other );
486  if ( ! result ) {
487  Py_DECREF( l );
488  return 0;
489  }
490 
491  return l;
492  }
493 
494 ////////////////////////////////////////////////////////////////////////////////
495 /// Implement python's __mul__ with the pythonized extend for TCollections.
496 
497  PyObject* TCollectionMul( ObjectProxy* self, PyObject* pymul )
498  {
499  Long_t imul = PyLong_AsLong( pymul );
500  if ( imul == -1 && PyErr_Occurred() )
501  return 0;
502 
503  if ( ! self->GetObject() ) {
504  PyErr_SetString( PyExc_TypeError, "unsubscriptable object" );
505  return 0;
506  }
507 
508  PyObject* nseq = BindCppObject(
509  Cppyy::Construct( self->ObjectIsA() ), self->ObjectIsA() );
510 
511  for ( Long_t i = 0; i < imul; ++i ) {
512  PyObject* result = CallPyObjMethod( nseq, "extend", (PyObject*)self );
513  Py_DECREF( result );
514  }
515 
516  return nseq;
517  }
518 
519 ////////////////////////////////////////////////////////////////////////////////
520 /// Implement python's __imul__ with the pythonized extend for TCollections.
521 
522  PyObject* TCollectionIMul( PyObject* self, PyObject* pymul )
523  {
524  Long_t imul = PyLong_AsLong( pymul );
525  if ( imul == -1 && PyErr_Occurred() )
526  return 0;
527 
528  PyObject* l = PySequence_List( self );
529 
530  for ( Long_t i = 0; i < imul - 1; ++i ) {
531  CallPyObjMethod( self, "extend", l );
532  }
533 
534  Py_INCREF( self );
535  return self;
536  }
537 
538 ////////////////////////////////////////////////////////////////////////////////
539 /// Implement a python-style count for TCollections.
540 
541  PyObject* TCollectionCount( PyObject* self, PyObject* obj )
542  {
543  Py_ssize_t count = 0;
544  for ( Py_ssize_t i = 0; i < PySequence_Size( self ); ++i ) {
545  PyObject* item = PySequence_GetItem( self, i );
546  PyObject* found = PyObject_RichCompare( item, obj, Py_EQ );
547 
548  Py_DECREF( item );
549 
550  if ( ! found )
551  return 0; // internal problem
552 
553  if ( PyObject_IsTrue( found ) )
554  count += 1;
555  Py_DECREF( found );
556  }
557 
558  return PyInt_FromSsize_t( count );
559  }
560 
561 ////////////////////////////////////////////////////////////////////////////////
562 /// Python __iter__ protocol for TCollections.
563 
564  PyObject* TCollectionIter( ObjectProxy* self ) {
565  if ( ! self->GetObject() ) {
566  PyErr_SetString( PyExc_TypeError, "iteration over non-sequence" );
567  return 0;
568  }
569 
570  TCollection* col =
571  (TCollection*)OP2TCLASS(self)->DynamicCast( TCollection::Class(), self->GetObject() );
572 
573  PyObject* pyobject = BindCppObject( (void*) new TIter( col ), "TIter" );
574  ((ObjectProxy*)pyobject)->HoldOn();
575  return pyobject;
576  }
577 
578 
579 //- TSeqCollection behavior ----------------------------------------------------
580  PyObject* TSeqCollectionGetItem( ObjectProxy* self, PySliceObject* index )
581  {
582  // Python-style indexing and size checking for getting objects from a TCollection.
583  if ( PySlice_Check( index ) ) {
584  if ( ! self->GetObject() ) {
585  PyErr_SetString( PyExc_TypeError, "unsubscriptable object" );
586  return 0;
587  }
588 
589  TClass* clSeq = OP2TCLASS(self);
590  TSeqCollection* oseq =
591  (TSeqCollection*)clSeq->DynamicCast( TSeqCollection::Class(), self->GetObject() );
592  TSeqCollection* nseq = (TSeqCollection*)clSeq->New();
593 
594  Py_ssize_t start, stop, step;
595  PySlice_GetIndices( (PyROOT_PySliceCast)index, oseq->GetSize(), &start, &stop, &step );
596 
597  for ( Py_ssize_t i = start; i < stop; i += step ) {
598  nseq->Add( oseq->At( (Int_t)i ) );
599  }
600 
601  return BindCppObject( (void*) nseq, clSeq->GetName() );
602  }
603 
604  return CallSelfIndex( self, (PyObject*)index, "At" );
605  }
606 
607 ////////////////////////////////////////////////////////////////////////////////
608 /// Python-style indexing and size checking for setting objects in a TCollection.
609 
610  PyObject* TSeqCollectionSetItem( ObjectProxy* self, PyObject* args )
611  {
612  PyObject* index = 0, *obj = 0;
613  if ( ! PyArg_ParseTuple( args,
614  const_cast< char* >( "OO:__setitem__" ), &index, &obj ) )
615  return 0;
616 
617  if ( PySlice_Check( index ) ) {
618  if ( ! self->GetObject() ) {
619  PyErr_SetString( PyExc_TypeError, "unsubscriptable object" );
620  return 0;
621  }
622 
624  TSeqCollection::Class(), self->GetObject() );
625 
626  Py_ssize_t start, stop, step;
627  PySlice_GetIndices( (PyROOT_PySliceCast)index, oseq->GetSize(), &start, &stop, &step );
628  for ( Py_ssize_t i = stop - step; i >= start; i -= step ) {
629  oseq->RemoveAt( (Int_t)i );
630  }
631 
632  for ( Py_ssize_t i = 0; i < PySequence_Size( obj ); ++i ) {
633  ObjectProxy* item = (ObjectProxy*)PySequence_GetItem( obj, i );
634  item->Release();
635  oseq->AddAt( (TObject*) item->GetObject(), (Int_t)(i + start) );
636  Py_DECREF( item );
637  }
638 
639  Py_INCREF( Py_None );
640  return Py_None;
641  }
642 
643  PyObject* pyindex = PyStyleIndex( (PyObject*)self, index );
644  if ( ! pyindex )
645  return 0;
646 
647  PyObject* result = CallPyObjMethod( (PyObject*)self, "RemoveAt", pyindex );
648  if ( ! result ) {
649  Py_DECREF( pyindex );
650  return 0;
651  }
652 
653  Py_DECREF( result );
654  result = CallPyObjMethod( (PyObject*)self, "AddAt", obj, pyindex );
655  Py_DECREF( pyindex );
656  return result;
657  }
658 
659 ////////////////////////////////////////////////////////////////////////////////
660 /// Implement python's __del__ with TCollection::RemoveAt.
661 
662  PyObject* TSeqCollectionDelItem( ObjectProxy* self, PySliceObject* index )
663  {
664  if ( PySlice_Check( index ) ) {
665  if ( ! self->GetObject() ) {
666  PyErr_SetString( PyExc_TypeError, "unsubscriptable object" );
667  return 0;
668  }
669 
671  TSeqCollection::Class(), self->GetObject() );
672 
673  Py_ssize_t start, stop, step;
674  PySlice_GetIndices( (PyROOT_PySliceCast)index, oseq->GetSize(), &start, &stop, &step );
675  for ( Py_ssize_t i = stop - step; i >= start; i -= step ) {
676  oseq->RemoveAt( (Int_t)i );
677  }
678 
679  Py_INCREF( Py_None );
680  return Py_None;
681  }
682 
683  PyObject* result = CallSelfIndex( self, (PyObject*)index, "RemoveAt" );
684  if ( ! result )
685  return 0;
686 
687  Py_DECREF( result );
688  Py_INCREF( Py_None );
689  return Py_None;
690  }
691 
692 ////////////////////////////////////////////////////////////////////////////////
693 /// Python-style insertion implemented with TCollection::AddAt.
694 
695  PyObject* TSeqCollectionInsert( PyObject* self, PyObject* args )
696  {
697  PyObject* obj = 0; Long_t idx = 0;
698  if ( ! PyArg_ParseTuple( args, const_cast< char* >( "lO:insert" ), &idx, &obj ) )
699  return 0;
700 
701  Py_ssize_t size = PySequence_Size( self );
702  if ( idx < 0 )
703  idx = 0;
704  else if ( size < idx )
705  idx = size;
706 
707  return CallPyObjMethod( self, "AddAt", obj, idx );
708  }
709 
710 ////////////////////////////////////////////////////////////////////////////////
711 /// Implement a python-style pop for TCollections.
712 
713  PyObject* TSeqCollectionPop( ObjectProxy* self, PyObject* args )
714  {
715  int nArgs = PyTuple_GET_SIZE( args );
716  if ( nArgs == 0 ) {
717  // create the default argument 'end of sequence'
718  PyObject* index = PyInt_FromSsize_t( PySequence_Size( (PyObject*)self ) - 1 );
719  PyObject* result = CallSelfIndex( self, index, "RemoveAt" );
720  Py_DECREF( index );
721  return result;
722  } else if ( nArgs != 1 ) {
723  PyErr_Format( PyExc_TypeError,
724  "pop() takes at most 1 argument (%d given)", nArgs );
725  return 0;
726  }
727 
728  return CallSelfIndex( self, PyTuple_GET_ITEM( args, 0 ), "RemoveAt" );
729  }
730 
731 ////////////////////////////////////////////////////////////////////////////////
732 /// Implement a python-style reverse for TCollections.
733 
734  PyObject* TSeqCollectionReverse( PyObject* self )
735  {
736  PyObject* tup = PySequence_Tuple( self );
737  if ( ! tup )
738  return 0;
739 
740  PyObject* result = CallPyObjMethod( self, "Clear" );
741  Py_XDECREF( result );
742 
743  for ( Py_ssize_t i = 0; i < PySequence_Size( tup ); ++i ) {
744  PyObject* retval = CallPyObjMethod( self, "AddAt", PyTuple_GET_ITEM( tup, i ), 0 );
745  Py_XDECREF( retval );
746  }
747 
748  Py_INCREF( Py_None );
749  return Py_None;
750  }
751 
752 ////////////////////////////////////////////////////////////////////////////////
753 /// Implement a python-style sort for TCollections.
754 
755  PyObject* TSeqCollectionSort( PyObject* self, PyObject* args, PyObject* kw )
756  {
757  if ( PyTuple_GET_SIZE( args ) == 0 && ! kw ) {
758  // no specialized sort, use ROOT one
759  return CallPyObjMethod( self, "Sort" );
760  } else {
761  // sort in a python list copy
762  PyObject* l = PySequence_List( self );
763  PyObject* result = 0;
764  if ( PyTuple_GET_SIZE( args ) == 1 )
765  result = CallPyObjMethod( l, "sort", PyTuple_GET_ITEM( args, 0 ) );
766  else {
767  PyObject* pymeth = PyObject_GetAttrString( l, const_cast< char* >( "sort" ) );
768  result = PyObject_Call( pymeth, args, kw );
769  Py_DECREF( pymeth );
770  }
771 
772  Py_XDECREF( result );
773  if ( PyErr_Occurred() ) {
774  Py_DECREF( l );
775  return 0;
776  }
777 
778  result = CallPyObjMethod( self, "Clear" );
779  Py_XDECREF( result );
780  result = CallPyObjMethod( self, "extend", l );
781  Py_XDECREF( result );
782  Py_DECREF( l );
783 
784  Py_INCREF( Py_None );
785  return Py_None;
786  }
787  }
788 
789 ////////////////////////////////////////////////////////////////////////////////
790 /// Implement a python-style index with TCollection::IndexOf.
791 
792  PyObject* TSeqCollectionIndex( PyObject* self, PyObject* obj )
793  {
794  PyObject* index = CallPyObjMethod( self, "IndexOf", obj );
795  if ( ! index )
796  return 0;
797 
798  if ( PyLong_AsLong( index ) < 0 ) {
799  Py_DECREF( index );
800  PyErr_SetString( PyExc_ValueError, "list.index(x): x not in list" );
801  return 0;
802  }
803 
804  return index;
805  }
806 
807 //- TObjArray behavior ---------------------------------------------------------
808  PyObject* TObjArrayLen( PyObject* self )
809  {
810  // GetSize on a TObjArray returns its capacity, not size in use
811  PyObject* size = CallPyObjMethod( self, "GetLast" );
812  if ( ! size )
813  return 0;
814 
815  long lsize = PyLong_AsLong( size );
816  if ( lsize == -1 && PyErr_Occurred() )
817  return 0;
818 
819  Py_DECREF( size );
820  return PyInt_FromLong( lsize + 1 );
821  }
822 
823 
824 //- TClonesArray behavior ------------------------------------------------------
825  PyObject* TClonesArraySetItem( ObjectProxy* self, PyObject* args )
826  {
827  // TClonesArray sets objects by constructing them in-place; which is impossible
828  // to support as the python object given as value must exist a priori. It can,
829  // however, be memcpy'd and stolen, caveat emptor.
830  ObjectProxy* pyobj = 0; PyObject* idx = 0;
831  if ( ! PyArg_ParseTuple( args,
832  const_cast< char* >( "OO!:__setitem__" ), &idx, &ObjectProxy_Type, &pyobj ) )
833  return 0;
834 
835  if ( ! self->GetObject() ) {
836  PyErr_SetString( PyExc_TypeError, "unsubscriptable object" );
837  return 0;
838  }
839 
840  PyObject* pyindex = PyStyleIndex( (PyObject*)self, idx );
841  if ( ! pyindex )
842  return 0;
843  int index = (int)PyLong_AsLong( pyindex );
844  Py_DECREF( pyindex );
845 
846  // get hold of the actual TClonesArray
847  TClonesArray* cla =
848  (TClonesArray*)OP2TCLASS(self)->DynamicCast( TClonesArray::Class(), self->GetObject() );
849 
850  if ( ! cla ) {
851  PyErr_SetString( PyExc_TypeError, "attempt to call with null object" );
852  return 0;
853  }
854 
855  if ( Cppyy::GetScope( cla->GetClass()->GetName() ) != pyobj->ObjectIsA() ) {
856  PyErr_Format( PyExc_TypeError, "require object of type %s, but %s given",
857  cla->GetClass()->GetName(), Cppyy::GetFinalName( pyobj->ObjectIsA() ).c_str() );
858  }
859 
860  // destroy old stuff, if applicable
861  if ( ((const TClonesArray&)*cla)[index] ) {
862  cla->RemoveAt( index );
863  }
864 
865  if ( pyobj->GetObject() ) {
866  // accessing an entry will result in new, unitialized memory (if properly used)
867  TObject* object = (*cla)[index];
868  pyobj->Release();
869  TMemoryRegulator::RegisterObject( pyobj, object );
870  memcpy( (void*)object, pyobj->GetObject(), cla->GetClass()->Size() );
871  }
872 
873  Py_INCREF( Py_None );
874  return Py_None;
875  }
876 
877 //- vector behavior as primitives ----------------------------------------------
878  typedef struct {
879  PyObject_HEAD
880  PyObject* vi_vector;
881  void* vi_data;
882  PyROOT::TConverter* vi_converter;
883  Py_ssize_t vi_pos;
884  Py_ssize_t vi_len;
885  Py_ssize_t vi_stride;
886  } vectoriterobject;
887 
888  static void vectoriter_dealloc( vectoriterobject* vi ) {
889  Py_XDECREF( vi->vi_vector );
890  delete vi->vi_converter;
891  PyObject_GC_Del( vi );
892  }
893 
894  static int vectoriter_traverse( vectoriterobject* vi, visitproc visit, void* arg ) {
895  Py_VISIT( vi->vi_vector );
896  return 0;
897  }
898 
899  static PyObject* vectoriter_iternext( vectoriterobject* vi ) {
900  if ( vi->vi_pos >= vi->vi_len )
901  return nullptr;
902 
903  PyObject* result = nullptr;
904 
905  if ( vi->vi_data && vi->vi_converter ) {
906  void* location = (void*)((ptrdiff_t)vi->vi_data + vi->vi_stride * vi->vi_pos );
907  result = vi->vi_converter->FromMemory( location );
908  } else {
909  PyObject* pyindex = PyLong_FromLong( vi->vi_pos );
910  result = CallPyObjMethod( (PyObject*)vi->vi_vector, "_vector__at", pyindex );
911  Py_DECREF( pyindex );
912  }
913 
914  vi->vi_pos += 1;
915  return result;
916  }
917 
918  PyTypeObject VectorIter_Type = {
919  PyVarObject_HEAD_INIT( &PyType_Type, 0 )
920  (char*)"ROOT.vectoriter", // tp_name
921  sizeof(vectoriterobject), // tp_basicsize
922  0,
923  (destructor)vectoriter_dealloc, // tp_dealloc
924  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
925  Py_TPFLAGS_DEFAULT |
926  Py_TPFLAGS_HAVE_GC, // tp_flags
927  0,
928  (traverseproc)vectoriter_traverse, // tp_traverse
929  0, 0, 0,
930  PyObject_SelfIter, // tp_iter
931  (iternextfunc)vectoriter_iternext, // tp_iternext
932  0, // tp_methods
933  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
934 #if PY_VERSION_HEX >= 0x02030000
935  , 0 // tp_del
936 #endif
937 #if PY_VERSION_HEX >= 0x02060000
938  , 0 // tp_version_tag
939 #endif
940 #if PY_VERSION_HEX >= 0x03040000
941  , 0 // tp_finalize
942 #endif
943  };
944 
945  static PyObject* vector_iter( PyObject* v ) {
946  vectoriterobject* vi = PyObject_GC_New( vectoriterobject, &VectorIter_Type );
947  if ( ! vi ) return NULL;
948 
949  Py_INCREF( v );
950  vi->vi_vector = v;
951 
952  PyObject* pyvalue_type = PyObject_GetAttrString( (PyObject*)Py_TYPE(v), "value_type" );
953  PyObject* pyvalue_size = PyObject_GetAttrString( (PyObject*)Py_TYPE(v), "value_size" );
954 
955  if ( pyvalue_type && pyvalue_size ) {
956  PyObject* pydata = CallPyObjMethod( v, "data" );
957  if ( Utility::GetBuffer( pydata, '*', 1, vi->vi_data, kFALSE ) == 0 )
958  vi->vi_data = nullptr;
959  Py_DECREF( pydata );
960 
961  vi->vi_converter = PyROOT::CreateConverter( PyROOT_PyUnicode_AsString( pyvalue_type ) );
962  vi->vi_stride = PyLong_AsLong( pyvalue_size );
963  } else {
964  PyErr_Clear();
965  vi->vi_data = nullptr;
966  vi->vi_converter = nullptr;
967  vi->vi_stride = 0;
968  }
969 
970  Py_XDECREF( pyvalue_size );
971  Py_XDECREF( pyvalue_type );
972 
973  vi->vi_len = vi->vi_pos = 0;
974  vi->vi_len = PySequence_Size( v );
975 
976  _PyObject_GC_TRACK( vi );
977  return (PyObject*)vi;
978  }
979 
980 
981  PyObject* VectorGetItem( ObjectProxy* self, PySliceObject* index )
982  {
983  // Implement python's __getitem__ for std::vector<>s.
984  if ( PySlice_Check( index ) ) {
985  if ( ! self->GetObject() ) {
986  PyErr_SetString( PyExc_TypeError, "unsubscriptable object" );
987  return 0;
988  }
989 
990  PyObject* pyclass = PyObject_GetAttr( (PyObject*)self, PyStrings::gClass );
991  PyObject* nseq = PyObject_CallObject( pyclass, NULL );
992  Py_DECREF( pyclass );
993 
994  Py_ssize_t start, stop, step;
995  PySlice_GetIndices( (PyROOT_PySliceCast)index, PyObject_Length( (PyObject*)self ), &start, &stop, &step );
996  for ( Py_ssize_t i = start; i < stop; i += step ) {
997  PyObject* pyidx = PyInt_FromSsize_t( i );
998  CallPyObjMethod( nseq, "push_back", CallPyObjMethod( (PyObject*)self, "_vector__at", pyidx ) );
999  Py_DECREF( pyidx );
1000  }
1001 
1002  return nseq;
1003  }
1004 
1005  return CallSelfIndex( self, (PyObject*)index, "_vector__at" );
1006  }
1007 
1008  PyObject* VectorBoolSetItem( ObjectProxy* self, PyObject* args )
1009  {
1010  // std::vector<bool> is a special-case in C++, and its return type depends on
1011  // the compiler: treat it special here as well
1012  int bval = 0; PyObject* idx = 0;
1013  if ( ! PyArg_ParseTuple( args, const_cast< char* >( "Oi:__setitem__" ), &idx, &bval ) )
1014  return 0;
1015 
1016  if ( ! self->GetObject() ) {
1017  PyErr_SetString( PyExc_TypeError, "unsubscriptable object" );
1018  return 0;
1019  }
1020 
1021  PyObject* pyindex = PyStyleIndex( (PyObject*)self, idx );
1022  if ( ! pyindex )
1023  return 0;
1024  int index = (int)PyLong_AsLong( pyindex );
1025  Py_DECREF( pyindex );
1026 
1027  std::string clName = Cppyy::GetFinalName( self->ObjectIsA() );
1028  std::string::size_type pos = clName.find( "vector<bool" );
1029  if ( pos != 0 && pos != 5 /* following std:: */ ) {
1030  PyErr_Format( PyExc_TypeError,
1031  "require object of type std::vector<bool>, but %s given",
1032  Cppyy::GetFinalName( self->ObjectIsA() ).c_str() );
1033  return 0;
1034  }
1035 
1036  // get hold of the actual std::vector<bool> (no cast, as vector is never a base)
1037  std::vector<bool>* vb = (std::vector<bool>*)self->GetObject();
1038 
1039  // finally, set the value
1040  (*vb)[ index ] = (bool)bval;
1041 
1042  Py_INCREF( Py_None );
1043  return Py_None;
1044  }
1045 
1046 //- map behavior as primitives ------------------------------------------------
1047  PyObject* MapContains( PyObject* self, PyObject* obj )
1048  {
1049  // Implement python's __contains__ for std::map<>s.
1050  PyObject* result = 0;
1051 
1052  PyObject* iter = CallPyObjMethod( self, "find", obj );
1053  if ( ObjectProxy_Check( iter ) ) {
1054  PyObject* end = CallPyObjMethod( self, "end" );
1055  if ( ObjectProxy_Check( end ) ) {
1056  if ( ! PyObject_RichCompareBool( iter, end, Py_EQ ) ) {
1057  Py_INCREF( Py_True );
1058  result = Py_True;
1059  }
1060  }
1061  Py_XDECREF( end );
1062  }
1063  Py_XDECREF( iter );
1064 
1065  if ( ! result ) {
1066  PyErr_Clear(); // e.g. wrong argument type, which should always lead to False
1067  Py_INCREF( Py_False );
1068  result = Py_False;
1069  }
1070 
1071  return result;
1072  }
1073 
1074 //- STL container iterator support --------------------------------------------
1075  PyObject* StlSequenceIter( PyObject* self )
1076  {
1077  // Implement python's __iter__ for std::iterator<>s.
1078  PyObject* iter = CallPyObjMethod( self, "begin" );
1079  if ( iter ) {
1080  PyObject* end = CallPyObjMethod( self, "end" );
1081  if ( end )
1082  PyObject_SetAttr( iter, PyStrings::gEnd, end );
1083  Py_XDECREF( end );
1084  }
1085  return iter;
1086  }
1087 
1088 //- safe indexing for STL-like vector w/o iterator dictionaries ---------------
1089  PyObject* CheckedGetItem( PyObject* self, PyObject* obj )
1090  {
1091  // Implement a generic python __getitem__ for std::vector<>s that are missing
1092  // their std::vector<>::iterator dictionary. This is then used for iteration
1093  // by means of consecutive index.
1094  Bool_t inbounds = kFALSE;
1095  Py_ssize_t size = PySequence_Size( self );
1096  Py_ssize_t idx = PyInt_AsSsize_t( obj );
1097  if ( 0 <= idx && 0 <= size && idx < size )
1098  inbounds = kTRUE;
1099 
1100  if ( inbounds ) {
1101  return CallPyObjMethod( self, "_getitem__unchecked", obj );
1102  } else if ( PyErr_Occurred() ) {
1103  // argument conversion problem: let method itself resolve anew and report
1104  PyErr_Clear();
1105  return CallPyObjMethod( self, "_getitem__unchecked", obj );
1106  } else {
1107  PyErr_SetString( PyExc_IndexError, "index out of range" );
1108  }
1109 
1110  return 0;
1111  }
1112 
1113 //- pair as sequence to allow tuple unpacking ---------------------------------
1114  PyObject* PairUnpack( PyObject* self, PyObject* pyindex )
1115  {
1116  // For std::map<> iteration, unpack std::pair<>s into tuples for the loop.
1117  Long_t idx = PyLong_AsLong( pyindex );
1118  if ( idx == -1 && PyErr_Occurred() )
1119  return 0;
1120 
1121  if ( ! ObjectProxy_Check( self ) || ! ((ObjectProxy*)self)->GetObject() ) {
1122  PyErr_SetString( PyExc_TypeError, "unsubscriptable object" );
1123  return 0;
1124  }
1125 
1126  if ( (int)idx == 0 )
1127  return PyObject_GetAttr( self, PyStrings::gFirst );
1128  else if ( (int)idx == 1 )
1129  return PyObject_GetAttr( self, PyStrings::gSecond );
1130 
1131  // still here? Trigger stop iteration
1132  PyErr_SetString( PyExc_IndexError, "out of bounds" );
1133  return 0;
1134  }
1135 
1136 //- string behavior as primitives ----------------------------------------------
1137 #if PY_VERSION_HEX >= 0x03000000
1138 // TODO: this is wrong, b/c it doesn't order
1139 static int PyObject_Compare( PyObject* one, PyObject* other ) {
1140  return ! PyObject_RichCompareBool( one, other, Py_EQ );
1141 }
1142 #endif
1143  static inline PyObject* PyROOT_PyString_FromCppString( std::string* s ) {
1144  return PyROOT_PyUnicode_FromStringAndSize( s->c_str(), s->size() );
1145  }
1146 
1147  static inline PyObject* PyROOT_PyString_FromCppString( TString* s ) {
1148  return PyROOT_PyUnicode_FromStringAndSize( s->Data(), s->Length() );
1149  }
1150 
1151  static inline PyObject* PyROOT_PyString_FromCppString( TObjString* s ) {
1153  }
1154 
1155 #define PYROOT_IMPLEMENT_STRING_PYTHONIZATION( type, name ) \
1156  inline PyObject* name##GetData( PyObject* self ) { \
1157  if ( PyROOT::ObjectProxy_Check( self ) ) { \
1158  type* obj = ((type*)((ObjectProxy*)self)->GetObject()); \
1159  if ( obj ) { \
1160  return PyROOT_PyString_FromCppString( obj ); \
1161  } else { \
1162  return ObjectProxy_Type.tp_str( self ); \
1163  } \
1164  } \
1165  PyErr_Format( PyExc_TypeError, "object mismatch (%s expected)", #type );\
1166  return 0; \
1167  } \
1168  \
1169  PyObject* name##StringRepr( PyObject* self ) \
1170  { \
1171  PyObject* data = name##GetData( self ); \
1172  if ( data ) { \
1173  PyObject* repr = PyROOT_PyUnicode_FromFormat( "\'%s\'", PyROOT_PyUnicode_AsString( data ) ); \
1174  Py_DECREF( data ); \
1175  return repr; \
1176  } \
1177  return 0; \
1178  } \
1179  \
1180  PyObject* name##StringIsEqual( PyObject* self, PyObject* obj ) \
1181  { \
1182  PyObject* data = name##GetData( self ); \
1183  if ( data ) { \
1184  PyObject* result = PyObject_RichCompare( data, obj, Py_EQ ); \
1185  Py_DECREF( data ); \
1186  return result; \
1187  } \
1188  return 0; \
1189  } \
1190  \
1191  PyObject* name##StringIsNotEqual( PyObject* self, PyObject* obj ) \
1192  { \
1193  PyObject* data = name##GetData( self ); \
1194  if ( data ) { \
1195  PyObject* result = PyObject_RichCompare( data, obj, Py_NE ); \
1196  Py_DECREF( data ); \
1197  return result; \
1198  } \
1199  return 0; \
1200  }
1201 
1202  // Only define StlStringCompare:
1203  // TStringCompare is unused and generates a warning;
1204 #define PYROOT_IMPLEMENT_STRING_PYTHONIZATION_CMP( type, name ) \
1205  PYROOT_IMPLEMENT_STRING_PYTHONIZATION( type, name ) \
1206  PyObject* name##StringCompare( PyObject* self, PyObject* obj ) \
1207  { \
1208  PyObject* data = name##GetData( self ); \
1209  int result = 0; \
1210  if ( data ) { \
1211  result = PyObject_Compare( data, obj ); \
1212  Py_DECREF( data ); \
1213  } \
1214  if ( PyErr_Occurred() ) \
1215  return 0; \
1216  return PyInt_FromLong( result ); \
1217  }
1218 
1219  PYROOT_IMPLEMENT_STRING_PYTHONIZATION_CMP( std::string, Stl )
1221 
1222 
1223 //- TObjString behavior --------------------------------------------------------
1225 
1226 ////////////////////////////////////////////////////////////////////////////////
1227 /// Implementation of python __len__ for TObjString.
1228 
1229  PyObject* TObjStringLength( PyObject* self )
1230  {
1231  PyObject* data = CallPyObjMethod( self, "GetName" );
1232  Py_ssize_t size = PySequence_Size( data );
1233  Py_DECREF( data );
1234  return PyInt_FromSsize_t( size );
1235  }
1236 
1237 
1238 //- TIter behavior -------------------------------------------------------------
1239  PyObject* TIterNext( PyObject* self )
1240  {
1241  // Implementation of python __next__ (iterator protocol) for TIter.
1242  PyObject* next = CallPyObjMethod( self, "Next" );
1243 
1244  if ( ! next )
1245  return 0;
1246 
1247  if ( ! PyObject_IsTrue( next ) ) {
1248  Py_DECREF( next );
1249  PyErr_SetString( PyExc_StopIteration, "" );
1250  return 0;
1251  }
1252 
1253  return next;
1254  }
1255 
1256 
1257 //- STL iterator behavior ------------------------------------------------------
1258  PyObject* StlIterNext( PyObject* self )
1259  {
1260  // Python iterator protocol __next__ for STL forward iterators.
1261  PyObject* next = 0;
1262  PyObject* last = PyObject_GetAttr( self, PyStrings::gEnd );
1263 
1264  if ( last != 0 ) {
1265  // handle special case of empty container (i.e. self is end)
1266  if ( PyObject_RichCompareBool( last, self, Py_EQ ) ) {
1267  PyErr_SetString( PyExc_StopIteration, "" );
1268  } else {
1269  PyObject* dummy = PyInt_FromLong( 1l );
1270  PyObject* iter = CallPyObjMethod( self, "__postinc__", dummy );
1271  Py_DECREF( dummy );
1272  if ( iter != 0 ) {
1273  if ( PyObject_RichCompareBool( last, iter, Py_EQ ) )
1274  PyErr_SetString( PyExc_StopIteration, "" );
1275  else
1276  next = CallPyObjMethod( iter, "__deref__" );
1277  } else {
1278  PyErr_SetString( PyExc_StopIteration, "" );
1279  }
1280  Py_XDECREF( iter );
1281  }
1282  } else {
1283  PyErr_SetString( PyExc_StopIteration, "" );
1284  }
1285 
1286  Py_XDECREF( last );
1287  return next;
1288  }
1289 
1290 ////////////////////////////////////////////////////////////////////////////////
1291 /// Called if operator== not available (e.g. if a global overload as under gcc).
1292 /// An exception is raised as the user should fix the dictionary.
1293 
1294  PyObject* StlIterIsEqual( PyObject* self, PyObject* other )
1295  {
1296  return PyErr_Format( PyExc_LookupError,
1297  "No operator==(const %s&, const %s&) available in the dictionary!",
1298  Utility::ClassName( self ).c_str(), Utility::ClassName( other ).c_str() );
1299  }
1300 
1301 ////////////////////////////////////////////////////////////////////////////////
1302 /// Called if operator!= not available (e.g. if a global overload as under gcc).
1303 /// An exception is raised as the user should fix the dictionary.
1304 
1305  PyObject* StlIterIsNotEqual( PyObject* self, PyObject* other )
1306  {
1307  return PyErr_Format( PyExc_LookupError,
1308  "No operator!=(const %s&, const %s&) available in the dictionary!",
1309  Utility::ClassName( self ).c_str(), Utility::ClassName( other ).c_str() );
1310  }
1311 
1312 
1313 //- TDirectory member templates ----------------------------------------------
1314  PyObject* TDirectoryGetObject( ObjectProxy* self, PyObject* args )
1315  {
1316  // Pythonization of TDirector::GetObject().
1317  PyObject* name = 0; ObjectProxy* ptr = 0;
1318  if ( ! PyArg_ParseTuple( args, const_cast< char* >( "O!O!:TDirectory::GetObject" ),
1319  &PyROOT_PyUnicode_Type, &name, &ObjectProxy_Type, &ptr ) )
1320  return 0;
1321 
1322  TDirectory* dir =
1323  (TDirectory*)OP2TCLASS(self)->DynamicCast( TDirectory::Class(), self->GetObject() );
1324 
1325  if ( ! dir ) {
1326  PyErr_SetString( PyExc_TypeError,
1327  "TDirectory::GetObject must be called with a TDirectory instance as first argument" );
1328  return 0;
1329  }
1330 
1331  void* address = dir->GetObjectChecked( PyROOT_PyUnicode_AsString( name ), OP2TCLASS(ptr) );
1332  if ( address ) {
1333  ptr->Set( address );
1334 
1335  Py_INCREF( Py_None );
1336  return Py_None;
1337  }
1338 
1339  PyErr_Format( PyExc_LookupError, "no such object, \"%s\"", PyROOT_PyUnicode_AsString( name ) );
1340  return 0;
1341  }
1342 
1343 ////////////////////////////////////////////////////////////////////////////////
1344 /// Type-safe version of TDirectory::WriteObjectAny, which is a template for
1345 /// the same reason on the C++ side.
1346 
1347  PyObject* TDirectoryWriteObject( ObjectProxy* self, PyObject* args )
1348  {
1349  ObjectProxy *wrt = 0; PyObject *name = 0, *option = 0;
1350  Int_t bufsize = 0;
1351  if ( ! PyArg_ParseTuple( args, const_cast< char* >( "O!O!|O!i:TDirectory::WriteObject" ),
1352  &ObjectProxy_Type, &wrt, &PyROOT_PyUnicode_Type, &name,
1353  &PyROOT_PyUnicode_Type, &option, &bufsize ) )
1354  return 0;
1355 
1356  TDirectory* dir =
1357  (TDirectory*)OP2TCLASS(self)->DynamicCast( TDirectory::Class(), self->GetObject() );
1358 
1359  if ( ! dir ) {
1360  PyErr_SetString( PyExc_TypeError,
1361  "TDirectory::WriteObject must be called with a TDirectory instance as first argument" );
1362  return 0;
1363  }
1364 
1365  Int_t result = 0;
1366  if ( option != 0 ) {
1367  result = dir->WriteObjectAny( wrt->GetObject(), OP2TCLASS(wrt),
1368  PyROOT_PyUnicode_AsString( name ), PyROOT_PyUnicode_AsString( option ), bufsize );
1369  } else {
1370  result = dir->WriteObjectAny(
1371  wrt->GetObject(), OP2TCLASS(wrt), PyROOT_PyUnicode_AsString( name ) );
1372  }
1373 
1374  return PyInt_FromLong( (Long_t)result );
1375  }
1376 
1377 }
1378 
1379 
1380 namespace PyROOT { // workaround for Intel icc on Linux
1381 
1382 //- TTree behavior ------------------------------------------------------------
1384  {
1385  // allow access to branches/leaves as if they are data members
1386  const char* name1 = PyROOT_PyUnicode_AsString( pyname );
1387  if ( ! name1 )
1388  return 0;
1389 
1390  // get hold of actual tree
1391  TTree* tree =
1392  (TTree*)OP2TCLASS(self)->DynamicCast( TTree::Class(), self->GetObject() );
1393 
1394  if ( ! tree ) {
1395  PyErr_SetString( PyExc_ReferenceError, "attempt to access a null-pointer" );
1396  return 0;
1397  }
1398 
1399  // deal with possible aliasing
1400  const char* name = tree->GetAlias( name1 );
1401  if ( ! name ) name = name1;
1402 
1403  // search for branch first (typical for objects)
1404  TBranch* branch = tree->GetBranch( name );
1405  if ( ! branch ) {
1406  // for benefit of naming of sub-branches, the actual name may have a trailing '.'
1407  branch = tree->GetBranch( (std::string( name ) + '.' ).c_str() );
1408  }
1409 
1410  if ( branch ) {
1411  // found a branched object, wrap its address for the object it represents
1412 
1413  // for partial return of a split object
1414  if ( branch->InheritsFrom(TBranchElement::Class()) ) {
1415  TBranchElement* be = (TBranchElement*)branch;
1416  if ( be->GetCurrentClass() && (be->GetCurrentClass() != be->GetTargetClass()) && (0 <= be->GetID()) ) {
1417  Long_t offset = ((TStreamerElement*)be->GetInfo()->GetElements()->At(be->GetID()))->GetOffset();
1419  }
1420  }
1421 
1422  // for return of a full object
1423  if ( branch->IsA() == TBranchElement::Class() || branch->IsA() == TBranchObject::Class() ) {
1424  TClass* klass = TClass::GetClass( branch->GetClassName() );
1425  if ( klass && branch->GetAddress() )
1426  return BindCppObjectNoCast( *(void**)branch->GetAddress(), Cppyy::GetScope( branch->GetClassName() ) );
1427 
1428  // try leaf, otherwise indicate failure by returning a typed null-object
1429  TObjArray* leaves = branch->GetListOfLeaves();
1430  if ( klass && ! tree->GetLeaf( name ) &&
1431  ! (leaves->GetSize() && ( leaves->First() == leaves->Last() ) ) )
1432  return BindCppObjectNoCast( NULL, Cppyy::GetScope( branch->GetClassName() ) );
1433  }
1434  }
1435 
1436  // if not, try leaf
1437  TLeaf* leaf = tree->GetLeaf( name );
1438  if ( branch && ! leaf ) {
1439  leaf = branch->GetLeaf( name );
1440  if ( ! leaf ) {
1441  TObjArray* leaves = branch->GetListOfLeaves();
1442  if ( leaves->GetSize() && ( leaves->First() == leaves->Last() ) ) {
1443  // i.e., if unambiguously only this one
1444  leaf = (TLeaf*)leaves->At( 0 );
1445  }
1446  }
1447  }
1448 
1449  if ( leaf ) {
1450  // found a leaf, extract value and wrap
1451  if ( 1 < leaf->GetLenStatic() || leaf->GetLeafCount() ) {
1452  // array types
1453  std::string typeName = leaf->GetTypeName();
1454  TConverter* pcnv = CreateConverter( typeName + '*', leaf->GetNdata() );
1455 
1456  void* address = 0;
1457  if ( leaf->GetBranch() ) address = (void*)leaf->GetBranch()->GetAddress();
1458  if ( ! address ) address = (void*)leaf->GetValuePointer();
1459 
1460  PyObject* value = pcnv->FromMemory( &address );
1461  delete pcnv;
1462 
1463  return value;
1464  } else if ( leaf->GetValuePointer() ) {
1465  // value types
1466  TConverter* pcnv = CreateConverter( leaf->GetTypeName() );
1467  PyObject* value = 0;
1468  if ( leaf->IsA() == TLeafElement::Class() || leaf->IsA() == TLeafObject::Class() )
1469  value = pcnv->FromMemory( (void*)*(void**)leaf->GetValuePointer() );
1470  else
1471  value = pcnv->FromMemory( (void*)leaf->GetValuePointer() );
1472  delete pcnv;
1473 
1474  return value;
1475  }
1476  }
1477 
1478  // confused
1479  PyErr_Format( PyExc_AttributeError,
1480  "\'%s\' object has no attribute \'%s\'", tree->IsA()->GetName(), name );
1481  return 0;
1482  }
1483 
1484 ////////////////////////////////////////////////////////////////////////////////
1485 
1486  class TTreeMemberFunction : public PyCallable {
1487  protected:
1488  TTreeMemberFunction( MethodProxy* org ) { Py_INCREF( org ); fOrg = org; }
1489  TTreeMemberFunction( const TTreeMemberFunction& t ) : PyCallable( t )
1490  {
1491  // Copy constructor; conform to python reference counting.
1492  Py_INCREF( t.fOrg );
1493  fOrg = t.fOrg;
1494  }
1495  TTreeMemberFunction& operator=( const TTreeMemberFunction& t )
1496  {
1497  // Assignment operator; conform to python reference counting.
1498  if ( &t != this ) {
1499  Py_INCREF( t.fOrg );
1500  Py_XDECREF( fOrg );
1501  fOrg = t.fOrg;
1502  }
1503  return *this;
1504  }
1505  ~TTreeMemberFunction() { Py_DECREF( fOrg ); fOrg = 0; }
1506 
1507  public:
1508  virtual PyObject* GetSignature() { return PyROOT_PyUnicode_FromString( "(...)" ); }
1509  virtual PyObject* GetPrototype() { return PyObject_GetAttrString( (PyObject*)fOrg, (char*)"__doc__" ); }
1510  virtual Int_t GetPriority() { return 100; }
1511  virtual PyObject* GetCoVarNames() {
1512  PyObject* co_varnames = PyTuple_New( 1 /* self */ + 1 /* fake */ );
1513  PyTuple_SET_ITEM( co_varnames, 0, PyROOT_PyUnicode_FromString( "self" ) );
1514  PyTuple_SET_ITEM( co_varnames, 1, PyROOT_PyUnicode_FromString( "*args" ) );
1515  return co_varnames;
1516  }
1517  virtual PyObject* GetArgDefault( Int_t ) { return NULL; }
1518  virtual PyObject* GetScopeProxy() { return CreateScopeProxy( "TTree" ); }
1519 
1520  protected:
1521  MethodProxy* fOrg;
1522  };
1523 
1524 ////////////////////////////////////////////////////////////////////////////////
1525 
1526  class TTreeBranch : public TTreeMemberFunction {
1527  public:
1528  TTreeBranch( MethodProxy* org ) : TTreeMemberFunction( org ) {}
1529 
1530  public:
1531  virtual Int_t GetMaxArgs() { return 5; }
1532  virtual PyCallable* Clone() { return new TTreeBranch( *this ); }
1533 
1534  virtual PyObject* Call(
1535  ObjectProxy*& self, PyObject* args, PyObject* kwds, TCallContext* /* ctxt */ )
1536  {
1537  // acceptable signatures:
1538  // ( const char*, void*, const char*, Int_t = 32000 )
1539  // ( const char*, const char*, T**, Int_t = 32000, Int_t = 99 )
1540  // ( const char*, T**, Int_t = 32000, Int_t = 99 )
1541  int argc = PyTuple_GET_SIZE( args );
1542 
1543  if ( 2 <= argc ) {
1544  TTree* tree =
1545  (TTree*)OP2TCLASS(self)->DynamicCast( TTree::Class(), self->GetObject() );
1546 
1547  if ( ! tree ) {
1548  PyErr_SetString( PyExc_TypeError,
1549  "TTree::Branch must be called with a TTree instance as first argument" );
1550  return 0;
1551  }
1552 
1553  PyObject *name = 0, *clName = 0, *leaflist = 0;
1554  PyObject *address = 0;
1555  PyObject *bufsize = 0, *splitlevel = 0;
1556 
1557  // try: ( const char*, void*, const char*, Int_t = 32000 )
1558  if ( PyArg_ParseTuple( args, const_cast< char* >( "O!OO!|O!:Branch" ),
1559  &PyROOT_PyUnicode_Type, &name, &address, &PyROOT_PyUnicode_Type,
1560  &leaflist, &PyInt_Type, &bufsize ) ) {
1561 
1562  void* buf = 0;
1563  if ( ObjectProxy_Check( address ) )
1564  buf = (void*)((ObjectProxy*)address)->GetObject();
1565  else
1566  Utility::GetBuffer( address, '*', 1, buf, kFALSE );
1567 
1568  if ( buf != 0 ) {
1569  TBranch* branch = 0;
1570  if ( argc == 4 ) {
1571  branch = tree->Branch( PyROOT_PyUnicode_AsString( name ), buf,
1572  PyROOT_PyUnicode_AsString( leaflist ), PyInt_AS_LONG( bufsize ) );
1573  } else {
1574  branch = tree->Branch( PyROOT_PyUnicode_AsString( name ), buf,
1575  PyROOT_PyUnicode_AsString( leaflist ) );
1576  }
1577 
1578  return BindCppObject( branch, "TBranch" );
1579  }
1580 
1581  }
1582  PyErr_Clear();
1583 
1584  // try: ( const char*, const char*, T**, Int_t = 32000, Int_t = 99 )
1585  // or: ( const char*, T**, Int_t = 32000, Int_t = 99 )
1586  Bool_t bIsMatch = kFALSE;
1587  if ( PyArg_ParseTuple( args, const_cast< char* >( "O!O!O|O!O!:Branch" ),
1588  &PyROOT_PyUnicode_Type, &name, &PyROOT_PyUnicode_Type, &clName, &address,
1589  &PyInt_Type, &bufsize, &PyInt_Type, &splitlevel ) ) {
1590  bIsMatch = kTRUE;
1591  } else {
1592  PyErr_Clear(); clName = 0; // clName no longer used
1593  if ( PyArg_ParseTuple( args, const_cast< char* >( "O!O|O!O!" ),
1594  &PyROOT_PyUnicode_Type, &name, &address,
1595  &PyInt_Type, &bufsize, &PyInt_Type, &splitlevel ) ) {
1596  bIsMatch = kTRUE;
1597  } else
1598  PyErr_Clear();
1599  }
1600 
1601  if ( bIsMatch == kTRUE ) {
1602  std::string klName = clName ? PyROOT_PyUnicode_AsString( clName ) : "";
1603  void* buf = 0;
1604 
1605  if ( ObjectProxy_Check( address ) ) {
1606  if ( ((ObjectProxy*)address)->fFlags & ObjectProxy::kIsReference )
1607  buf = (void*)((ObjectProxy*)address)->fObject;
1608  else
1609  buf = (void*)&((ObjectProxy*)address)->fObject;
1610 
1611  if ( ! clName ) {
1612  klName = OP2TCLASS((ObjectProxy*)address)->GetName();
1613  argc += 1;
1614  }
1615  } else
1616  Utility::GetBuffer( address, '*', 1, buf, kFALSE );
1617 
1618  if ( buf != 0 && klName != "" ) {
1619  TBranch* branch = 0;
1620  if ( argc == 3 ) {
1621  branch = tree->Branch( PyROOT_PyUnicode_AsString( name ), klName.c_str(), buf );
1622  } else if ( argc == 4 ) {
1623  branch = tree->Branch( PyROOT_PyUnicode_AsString( name ), klName.c_str(), buf,
1624  PyInt_AS_LONG( bufsize ) );
1625  } else if ( argc == 5 ) {
1626  branch = tree->Branch( PyROOT_PyUnicode_AsString( name ), klName.c_str(), buf,
1627  PyInt_AS_LONG( bufsize ), PyInt_AS_LONG( splitlevel ) );
1628  }
1629 
1630  return BindCppObject( branch, "TBranch" );
1631  }
1632  }
1633  }
1634 
1635  // still here? Then call original Branch() to reach the other overloads:
1636  Py_INCREF( (PyObject*)self );
1637  fOrg->fSelf = self;
1638  PyObject* result = PyObject_Call( (PyObject*)fOrg, args, kwds );
1639  fOrg->fSelf = 0;
1640  Py_DECREF( (PyObject*)self );
1641 
1642  return result;
1643  }
1644  };
1645 
1646 ////////////////////////////////////////////////////////////////////////////////
1647 
1648  class TTreeSetBranchAddress : public TTreeMemberFunction {
1649  public:
1650  TTreeSetBranchAddress( MethodProxy* org ) : TTreeMemberFunction( org ) {}
1651 
1652  public:
1653  virtual PyObject* GetPrototype()
1654  {
1655  return PyROOT_PyUnicode_FromString( "TBranch* TTree::SetBranchAddress( ... )" );
1656  }
1657 
1658  virtual Int_t GetMaxArgs() { return 2; }
1659  virtual PyCallable* Clone() { return new TTreeSetBranchAddress( *this ); }
1660 
1661  virtual PyObject* Call(
1662  ObjectProxy*& self, PyObject* args, PyObject* kwds, TCallContext* /* ctxt */ )
1663  {
1664  // acceptable signature:
1665  // ( const char*, void* )
1666  int argc = PyTuple_GET_SIZE( args );
1667 
1668  if ( 2 == argc ) {
1669  TTree* tree =
1670  (TTree*)OP2TCLASS(self)->DynamicCast( TTree::Class(), self->GetObject() );
1671 
1672  if ( ! tree ) {
1673  PyErr_SetString( PyExc_TypeError,
1674  "TTree::SetBranchAddress must be called with a TTree instance as first argument" );
1675  return 0;
1676  }
1677 
1678  PyObject *name = 0, *address = 0;
1679 
1680  // try: ( const char*, void* )
1681  if ( PyArg_ParseTuple( args, const_cast< char* >( "SO:SetBranchAddress" ),
1682  &name, &address ) ) {
1683 
1684  void* buf = 0;
1685  if ( ObjectProxy_Check( address ) ) {
1686  if ( ((ObjectProxy*)address)->fFlags & ObjectProxy::kIsReference )
1687  buf = (void*)((ObjectProxy*)address)->fObject;
1688  else
1689  buf = (void*)&((ObjectProxy*)address)->fObject;
1690  } else
1691  Utility::GetBuffer( address, '*', 1, buf, kFALSE );
1692 
1693  if ( buf != 0 ) {
1694  tree->SetBranchAddress( PyROOT_PyUnicode_AsString( name ), buf );
1695 
1696  Py_INCREF( Py_None );
1697  return Py_None;
1698  }
1699  }
1700  }
1701 
1702  // still here? Then call original Branch() to reach the other overloads:
1703  Py_INCREF( (PyObject*)self );
1704  fOrg->fSelf = self;
1705  PyObject* result = PyObject_Call( (PyObject*)fOrg, args, kwds );
1706  fOrg->fSelf = 0;
1707  Py_DECREF( (PyObject*)self );
1708 
1709  return result;
1710  }
1711 
1712  protected:
1713  virtual PyObject* ReportTypeError()
1714  {
1715  PyErr_SetString( PyExc_TypeError,
1716  "TTree::SetBranchAddress must be called with a TTree instance as first argument" );
1717  return 0;
1718  }
1719  };
1720 
1721 
1722 // TChain overrides TTree's SetBranchAddress, so set it again (the python method only forwards
1723 // onto a TTree*, so the C++ virtual function call will make sure the right method is used)
1724  class TChainSetBranchAddress : public TTreeSetBranchAddress {
1725  public:
1726  TChainSetBranchAddress( MethodProxy* org ) : TTreeSetBranchAddress( org ) {}
1727 
1728  public:
1729  virtual PyObject* GetPrototype()
1730  {
1731  return PyROOT_PyUnicode_FromString( "TBranch* TChain::SetBranchAddress( ... )" );
1732  }
1733 
1734  virtual Int_t GetMaxArgs() { return 2; }
1735  virtual PyCallable* Clone() { return new TChainSetBranchAddress( *this ); }
1736 
1737  protected:
1738  virtual PyObject* ReportTypeError()
1739  {
1740  PyErr_SetString( PyExc_TypeError,
1741  "TChain::SetBranchAddress must be called with a TChain instance as first argument" );
1742  return 0;
1743  }
1744  };
1745 
1746 //- TMinuit behavior ----------------------------------------------------------
1747  void TMinuitPyCallback( void* vpyfunc, Long_t /* npar */,
1748  Int_t& a0, Double_t* a1, Double_t& a2, Double_t* a3, Int_t a4 ) {
1749  // a void* was passed to keep the interface on builtin types only
1750  PyObject* pyfunc = (PyObject*)vpyfunc;
1751 
1752  // prepare arguments
1753  PyObject* pya0 = BufFac_t::Instance()->PyBuffer_FromMemory( &a0, 1 );
1754  PyObject* pya1 = BufFac_t::Instance()->PyBuffer_FromMemory( a1, a0 );
1755  PyObject* pya2 = BufFac_t::Instance()->PyBuffer_FromMemory( &a2, 1 );
1756  PyObject* pya3 = BufFac_t::Instance()->PyBuffer_FromMemory( a3, -1 ); // size unknown
1757 
1758  if ( ! (pya0 && pya1 && pya2 && pya3) ) {
1759  Py_XDECREF( pya3 ); Py_XDECREF( pya2 ); Py_XDECREF( pya1 ); Py_XDECREF( pya0 );
1760  return;
1761  }
1762 
1763  // perform actual call
1764  PyObject* result = PyObject_CallFunction(
1765  pyfunc, (char*)"OOOOi", pya0, pya1, pya2, pya3, a4 );
1766  Py_DECREF( pya3 ); Py_DECREF( pya2 ); Py_DECREF( pya1 ); Py_DECREF( pya0 );
1767 
1768  if ( ! result ) {
1769  PyErr_Print();
1770  throw std::runtime_error( "TMinuit python fit function call failed" );
1771  }
1772 
1773  Py_XDECREF( result );
1774  }
1775 
1776 //- TFN behavior --------------------------------------------------------------
1777  double TFNPyCallback( void* vpyfunc, Long_t npar, double* a0, double* a1 ) {
1778  // a void* was passed to keep the interface on builtin types only
1779  PyObject* pyfunc = (PyObject*)vpyfunc;
1780 
1781  // prepare arguments and call
1782  PyObject* pya0 = BufFac_t::Instance()->PyBuffer_FromMemory( a0, 4 );
1783  if ( ! pya0 )
1784  return 0.;
1785 
1786  PyObject* result = 0;
1787  if ( npar != 0 ) {
1788  PyObject* pya1 = BufFac_t::Instance()->PyBuffer_FromMemory( a1, npar );
1789  result = PyObject_CallFunction( pyfunc, (char*)"OO", pya0, pya1 );
1790  Py_DECREF( pya1 );
1791  } else
1792  result = PyObject_CallFunction( pyfunc, (char*)"O", pya0 );
1793 
1794  Py_DECREF( pya0 );
1795 
1796  // translate result, throw if an error has occurred
1797  double d = 0.;
1798  if ( ! result ) {
1799  PyErr_Print();
1800  throw std::runtime_error( "TFN python function call failed" );
1801  } else {
1802  d = PyFloat_AsDouble( result );
1803  Py_DECREF( result );
1804  }
1805 
1806  return d;
1807  }
1808 
1809 } // namespace PyROOT
1810 
1811 
1812 namespace {
1813 
1814 // for convenience
1815  using namespace PyROOT;
1816 
1817 //- THN behavior --------------------------------------------------------------
1818  PyObject* THNIMul( PyObject* self, PyObject* scale )
1819  {
1820  // Use THN::Scale to perform *= ... need this stub to return self.
1821  PyObject* result = CallPyObjMethod( self, "Scale", scale );
1822  if ( ! result )
1823  return result;
1824 
1825  Py_DECREF( result );
1826  Py_INCREF( self );
1827  return self;
1828  }
1829 
1830 
1831 ////////////////////////////////////////////////////////////////////////////////
1832 
1833  class TPretendInterpreted: public PyCallable {
1834  public:
1835  TPretendInterpreted( int nArgs ) : fNArgs( nArgs ) {}
1836 
1837  public:
1838  Int_t GetNArgs() { return fNArgs; }
1839  virtual Int_t GetPriority() { return 100; }
1840  virtual Int_t GetMaxArgs() { return GetNArgs()+1; }
1841  virtual PyObject* GetCoVarNames() {
1842  PyObject* co_varnames = PyTuple_New( 1 /* self */ + 1 /* fake */ );
1843  PyTuple_SET_ITEM( co_varnames, 0, PyROOT_PyUnicode_FromString( "self" ) );
1844  PyTuple_SET_ITEM( co_varnames, 1, PyROOT_PyUnicode_FromString( "*args" ) );
1845  return co_varnames;
1846  }
1847  virtual PyObject* GetArgDefault( Int_t ) { return NULL; }
1848 
1849  Bool_t IsCallable( PyObject* pyobject )
1850  {
1851  // Determine whether the given pyobject is indeed callable.
1852  if ( ! pyobject || ! PyCallable_Check( pyobject ) ) {
1853  PyObject* str = pyobject ? PyObject_Str( pyobject ) : PyROOT_PyUnicode_FromString( "null pointer" );
1854  PyErr_Format( PyExc_ValueError,
1855  "\"%s\" is not a valid python callable", PyROOT_PyUnicode_AsString( str ) );
1856  Py_DECREF( str );
1857  return kFALSE;
1858  }
1859 
1860  return kTRUE;
1861  }
1862 
1863  private:
1864  Int_t fNArgs;
1865  };
1866 
1867 ////////////////////////////////////////////////////////////////////////////////
1868 
1869  class TF1InitWithPyFunc : public TPretendInterpreted {
1870  public:
1871  TF1InitWithPyFunc( int ntf = 1 ) : TPretendInterpreted( 2 + 2*ntf ) {}
1872 
1873  public:
1874  virtual PyObject* GetSignature() { return PyROOT_PyUnicode_FromString( "(...)" ); }
1875  virtual PyObject* GetPrototype()
1876  {
1878  "TF1::TF1(const char* name, PyObject* callable, "
1879  "Double_t xmin, Double_t xmax, Int_t npar = 0)" );
1880  }
1881  virtual PyObject* GetScopeProxy() { return CreateScopeProxy( "TF1" ); }
1882  virtual PyCallable* Clone() { return new TF1InitWithPyFunc( *this ); }
1883 
1884  virtual PyObject* Call(
1885  ObjectProxy*& self, PyObject* args, PyObject* /* kwds */, TCallContext* /* ctxt */ )
1886  {
1887  // expected signature: ( char* name, pyfunc, double xmin, double xmax, int npar = 0 )
1888  int argc = PyTuple_GET_SIZE( args );
1889  const int reqNArgs = GetNArgs();
1890  if ( ! ( argc == reqNArgs || argc == reqNArgs+1 ) ) {
1891  PyErr_Format( PyExc_TypeError,
1892  "TFN::TFN(const char*, PyObject* callable, ...) =>\n"
1893  " takes at least %d and at most %d arguments (%d given)",
1894  reqNArgs, reqNArgs+1, argc );
1895  return 0; // reported as an overload failure
1896  }
1897 
1898  PyObject* pyfunc = PyTuple_GET_ITEM( args, 1 );
1899 
1900  // verify/setup the callback parameters
1901  Long_t npar = 0; // default value if not given
1902  if ( argc == reqNArgs+1 )
1903  npar = PyInt_AsLong( PyTuple_GET_ITEM( args, reqNArgs ) );
1904 
1905  // create signature
1906  std::vector<std::string> signature; signature.reserve( 2 );
1907  signature.push_back( "double*" );
1908  signature.push_back( "double*" );
1909 
1910  // registration with Cling
1911  void* fptr = Utility::CreateWrapperMethod(
1912  pyfunc, npar, "double", signature, "TFNPyCallback" );
1913  if ( ! fptr /* PyErr was set */ )
1914  return 0;
1915 
1916  // get constructor
1917  MethodProxy* method =
1918  (MethodProxy*)PyObject_GetAttr( (PyObject*)self, PyStrings::gInit );
1919 
1920  // build new argument array
1921  PyObject* newArgs = PyTuple_New( reqNArgs + 1 );
1922 
1923  for ( int iarg = 0; iarg < argc; ++iarg ) {
1924  PyObject* item = PyTuple_GET_ITEM( args, iarg );
1925  if ( iarg != 1 ) {
1926  Py_INCREF( item );
1927  PyTuple_SET_ITEM( newArgs, iarg, item );
1928  } else {
1929  PyTuple_SET_ITEM( newArgs, iarg, PyROOT_PyCapsule_New( fptr, NULL, NULL ) );
1930  }
1931  }
1932 
1933  if ( argc == reqNArgs ) // meaning: use default for last value
1934  PyTuple_SET_ITEM( newArgs, reqNArgs, PyInt_FromLong( 0l ) );
1935 
1936  // re-run constructor, will select the proper one with void* for callback
1937  PyObject* result = PyObject_CallObject( (PyObject*)method, newArgs );
1938 
1939  // done, may have worked, if not: 0 is returned
1940  Py_DECREF( newArgs );
1941  Py_DECREF( method );
1942  return result;
1943  }
1944  };
1945 
1946 ////////////////////////////////////////////////////////////////////////////////
1947 
1948  class TF2InitWithPyFunc : public TF1InitWithPyFunc {
1949  public:
1950  TF2InitWithPyFunc() : TF1InitWithPyFunc( 2 ) {}
1951 
1952  public:
1953  virtual PyObject* GetPrototype()
1954  {
1956  "TF2::TF2(const char* name, PyObject* callable, "
1957  "Double_t xmin, Double_t xmax, "
1958  "Double_t ymin, Double_t ymax, Int_t npar = 0)" );
1959  }
1960  virtual PyObject* GetScopeProxy() { return CreateScopeProxy( "TF2" ); }
1961  virtual PyCallable* Clone() { return new TF2InitWithPyFunc( *this ); }
1962  };
1963 
1964 ////////////////////////////////////////////////////////////////////////////////
1965 
1966  class TF3InitWithPyFunc : public TF1InitWithPyFunc {
1967  public:
1968  TF3InitWithPyFunc() : TF1InitWithPyFunc( 3 ) {}
1969 
1970  public:
1971  virtual PyObject* GetPrototype()
1972  {
1974  "TF3::TF3(const char* name, PyObject* callable, "
1975  "Double_t xmin, Double_t xmax, "
1976  "Double_t ymin, Double_t ymax, "
1977  "Double_t zmin, Double_t zmax, Int_t npar = 0)" );
1978  }
1979  virtual PyObject* GetScopeProxy() { return CreateScopeProxy( "TF3" ); }
1980  virtual PyCallable* Clone() { return new TF3InitWithPyFunc( *this ); }
1981  };
1982 
1983 //- TFunction behavior ---------------------------------------------------------
1984  PyObject* TFunctionCall( ObjectProxy*& self, PyObject* args ) {
1985  return TFunctionHolder( Cppyy::gGlobalScope, (Cppyy::TCppMethod_t)self->GetObject() ).Call( self, args, 0 );
1986  }
1987 
1988 
1989 //- TMinuit behavior -----------------------------------------------------------
1990  class TMinuitSetFCN : public TPretendInterpreted {
1991  public:
1992  TMinuitSetFCN( int nArgs = 1 ) : TPretendInterpreted( nArgs ) {}
1993 
1994  public:
1995  virtual PyObject* GetSignature() { return PyROOT_PyUnicode_FromString( "(PyObject* callable)" ); }
1996  virtual PyObject* GetPrototype()
1997  {
1999  "TMinuit::SetFCN(PyObject* callable)" );
2000  }
2001  virtual PyObject* GetScopeProxy() { return CreateScopeProxy( "TMinuit" ); }
2002  virtual PyCallable* Clone() { return new TMinuitSetFCN( *this ); }
2003 
2004  virtual PyObject* Call(
2005  ObjectProxy*& self, PyObject* args, PyObject* kwds, TCallContext* ctxt )
2006  {
2007  // expected signature: ( pyfunc )
2008  int argc = PyTuple_GET_SIZE( args );
2009  if ( argc != 1 ) {
2010  PyErr_Format( PyExc_TypeError,
2011  "TMinuit::SetFCN(PyObject* callable, ...) =>\n"
2012  " takes exactly 1 argument (%d given)", argc );
2013  return 0; // reported as an overload failure
2014  }
2015 
2016  PyObject* pyfunc = PyTuple_GET_ITEM( args, 0 );
2017  if ( ! IsCallable( pyfunc ) )
2018  return 0;
2019 
2020  // create signature
2021  std::vector<std::string> signature; signature.reserve( 5 );
2022  signature.push_back( "Int_t&" );
2023  signature.push_back( "Double_t*" );
2024  signature.push_back( "Double_t&" );
2025  signature.push_back( "Double_t*" );
2026  signature.push_back( "Int_t" );
2027 
2028  // registration with Cling
2029  void* fptr = Utility::CreateWrapperMethod(
2030  pyfunc, 5, "void", signature, "TMinuitPyCallback" );
2031  if ( ! fptr /* PyErr was set */ )
2032  return 0;
2033 
2034  // get setter function
2035  MethodProxy* method =
2036  (MethodProxy*)PyObject_GetAttr( (PyObject*)self, PyStrings::gSetFCN );
2037 
2038  // CLING WORKAROUND: SetFCN(void* fun) is deprecated but for whatever reason
2039  // still available yet not functional; select the correct one based on its
2040  // signature of the full function pointer
2041  PyCallable* setFCN = 0;
2042  const MethodProxy::Methods_t& methods = method->fMethodInfo->fMethods;
2043  for ( MethodProxy::Methods_t::const_iterator im = methods.begin(); im != methods.end(); ++im ) {
2044  PyObject* sig = (*im)->GetSignature();
2045  if ( sig && strstr( PyROOT_PyUnicode_AsString( sig ), "Double_t&" ) ) {
2046  // the comparison was not exact, but this is just a workaround
2047  setFCN = *im;
2048  Py_DECREF( sig );
2049  break;
2050  }
2051  Py_DECREF( sig );
2052  }
2053  if ( ! setFCN ) // this never happens but Coverity insists; it can be
2054  return 0; // removed with the workaround in due time
2055  // END CLING WORKAROUND
2056 
2057  // build new argument array
2058  PyObject* newArgs = PyTuple_New( 1 );
2059  PyTuple_SET_ITEM( newArgs, 0, PyROOT_PyCapsule_New( fptr, NULL, NULL ) );
2060 
2061  // re-run
2062  // CLING WORKAROUND: this is to be the call once TMinuit is fixed:
2063  // PyObject* result = PyObject_CallObject( (PyObject*)method, newArgs );
2064  PyObject* result = setFCN->Call( self, newArgs, kwds, ctxt );
2065  // END CLING WORKAROUND
2066 
2067  // done, may have worked, if not: 0 is returned
2068  Py_DECREF( newArgs );
2069  Py_DECREF( method );
2070  return result;
2071  }
2072  };
2073 
2074  class TMinuitFitterSetFCN : public TMinuitSetFCN {
2075  public:
2076  TMinuitFitterSetFCN() : TMinuitSetFCN( 1 ) {}
2077 
2078  public:
2079  virtual PyObject* GetPrototype()
2080  {
2082  "TMinuitFitter::SetFCN(PyObject* callable)" );
2083  }
2084 
2085  virtual PyCallable* Clone() { return new TMinuitFitterSetFCN( *this ); }
2086 
2087  virtual PyObject* Call(
2088  ObjectProxy*& self, PyObject* args, PyObject* kwds, TCallContext* ctxt )
2089  {
2090  // expected signature: ( pyfunc )
2091  int argc = PyTuple_GET_SIZE( args );
2092  if ( argc != 1 ) {
2093  PyErr_Format( PyExc_TypeError,
2094  "TMinuitFitter::SetFCN(PyObject* callable, ...) =>\n"
2095  " takes exactly 1 argument (%d given)", argc );
2096  return 0; // reported as an overload failure
2097  }
2098 
2099  return TMinuitSetFCN::Call( self, args, kwds, ctxt );
2100  }
2101  };
2102 
2103 //- Fit::TFitter behavior ------------------------------------------------------
2104  PyObject* gFitterPyCallback = 0;
2105 
2106  void FitterPyCallback( int& npar, double* gin, double& f, double* u, int flag )
2107  {
2108  // Cling-callable callback for Fit::Fitter derived objects.
2109  PyObject* result = 0;
2110 
2111  // prepare arguments
2112  PyObject* arg1 = BufFac_t::Instance()->PyBuffer_FromMemory( &npar );
2113 
2115 
2116  PyObject* arg3 = PyList_New( 1 );
2117  PyList_SetItem( arg3, 0, PyFloat_FromDouble( f ) );
2118 
2119  PyObject* arg4 = BufFac_t::Instance()->PyBuffer_FromMemory( u, npar );
2120 
2121  // perform actual call
2122  result = PyObject_CallFunction(
2123  gFitterPyCallback, (char*)"OOOOi", arg1, arg2, arg3, arg4, flag );
2124  f = PyFloat_AsDouble( PyList_GetItem( arg3, 0 ) );
2125 
2126  Py_DECREF( arg4 ); Py_DECREF( arg3 ); Py_DECREF( arg2 ); Py_DECREF( arg1 );
2127 
2128  if ( ! result ) {
2129  PyErr_Print();
2130  throw std::runtime_error( "TMinuit python fit function call failed" );
2131  }
2132 
2133  Py_XDECREF( result );
2134  }
2135 
2136  class TFitterFitFCN : public TPretendInterpreted {
2137  public:
2138  TFitterFitFCN() : TPretendInterpreted( 2 ) {}
2139 
2140  public:
2141  virtual PyObject* GetSignature()
2142  {
2144  "(PyObject* callable, int npar = 0, const double* params = 0, unsigned int dataSize = 0, bool chi2fit = false)" );
2145  }
2146  virtual PyObject* GetPrototype()
2147  {
2149  "TFitter::FitFCN(PyObject* callable, int npar = 0, const double* params = 0, unsigned int dataSize = 0, bool chi2fit = false)" );
2150  }
2151  virtual PyObject* GetScopeProxy() { return CreateScopeProxy( "TFitter" ); }
2152  virtual PyCallable* Clone() { return new TFitterFitFCN( *this ); }
2153 
2154  virtual PyObject* Call(
2155  ObjectProxy*& self, PyObject* args, PyObject* /* kwds */, TCallContext* /* ctxt */ )
2156  {
2157  // expected signature: ( self, pyfunc, int npar = 0, const double* params = 0, unsigned int dataSize = 0, bool chi2fit = false )
2158  int argc = PyTuple_GET_SIZE( args );
2159  if ( argc < 1 ) {
2160  PyErr_Format( PyExc_TypeError,
2161  "TFitter::FitFCN(PyObject* callable, ...) =>\n"
2162  " takes at least 1 argument (%d given)", argc );
2163  return 0; // reported as an overload failure
2164  }
2165 
2166  PyObject* pyfunc = PyTuple_GET_ITEM( args, 0 );
2167  if ( ! IsCallable( pyfunc ) )
2168  return 0;
2169 
2170  // global registration
2171  Py_XDECREF( gFitterPyCallback );
2172  Py_INCREF( pyfunc );
2173  gFitterPyCallback = pyfunc;
2174 
2175  // get function
2176  MethodProxy* method =
2177  (MethodProxy*)PyObject_GetAttr( (PyObject*)self, PyStrings::gFitFCN );
2178 
2179  // build new argument array
2180  PyObject* newArgs = PyTuple_New( argc );
2181  PyTuple_SET_ITEM( newArgs, 0, PyROOT_PyCapsule_New( (void*)FitterPyCallback, NULL, NULL ) );
2182  for ( int iarg = 1; iarg < argc; ++iarg ) {
2183  PyObject* pyarg = PyTuple_GET_ITEM( args, iarg );
2184  Py_INCREF( pyarg );
2185  PyTuple_SET_ITEM( newArgs, iarg, pyarg );
2186  }
2187 
2188  // re-run
2189  PyObject* result = PyObject_CallObject( (PyObject*)method, newArgs );
2190 
2191  // done, may have worked, if not: 0 is returned
2192  Py_DECREF( newArgs );
2193  Py_DECREF( method );
2194  return result;
2195  }
2196  };
2197 
2198 
2199 //- TFile::Get -----------------------------------------------------------------
2200  PyObject* TFileGetAttr( PyObject* self, PyObject* attr )
2201  {
2202  // Pythonization of TFile::Get that raises AttributeError on failure.
2203  PyObject* result = CallPyObjMethod( self, "Get", attr );
2204  if ( !result )
2205  return result;
2206 
2207  if ( !PyObject_IsTrue( result ) ) {
2208  PyObject* astr = PyObject_Str( attr );
2209  PyErr_Format( PyExc_AttributeError, "TFile object has no attribute \'%s\'",
2210  PyROOT_PyUnicode_AsString( astr ) );
2211  Py_DECREF( astr );
2212  Py_DECREF( result );
2213  return 0;
2214  }
2215  return result;
2216  }
2217 
2218 // This is done for TFile, but Get() is really defined in TDirectoryFile and its base
2219 // TDirectory suffers from a similar problem. Nevertheless, the TFile case is by far
2220 // the most common, so we'll leave it at this until someone asks for one of the bases
2221 // to be pythonized.
2222  PyObject* TDirectoryFileGet( ObjectProxy* self, PyObject* pynamecycle )
2223  {
2224  // Pythonization of TDirectoryFile::Get that handles non-TObject deriveds
2225  if ( ! ObjectProxy_Check( self ) ) {
2226  PyErr_SetString( PyExc_TypeError,
2227  "TDirectoryFile::Get must be called with a TDirectoryFile instance as first argument" );
2228  return nullptr;
2229  }
2230 
2231  TDirectoryFile* dirf =
2232  (TDirectoryFile*)OP2TCLASS(self)->DynamicCast( TDirectoryFile::Class(), self->GetObject() );
2233  if ( !dirf ) {
2234  PyErr_SetString( PyExc_ReferenceError, "attempt to access a null-pointer" );
2235  return nullptr;
2236  }
2237 
2238  const char* namecycle = PyROOT_PyUnicode_AsString( pynamecycle );
2239  if ( !namecycle )
2240  return nullptr; // TypeError already set
2241 
2242  TKey* key = dirf->GetKey( namecycle );
2243  if ( key ) {
2244  void* addr = dirf->GetObjectChecked( namecycle, key->GetClassName() );
2245  return BindCppObjectNoCast( addr,
2247  }
2248 
2249  // no key? for better or worse, call normal Get()
2250  void* addr = dirf->Get( namecycle );
2251  return BindCppObject( addr, (Cppyy::TCppType_t)Cppyy::GetScope( "TObject" ), kFALSE );
2252  }
2253 
2254 
2255 //- simplistic len() functions -------------------------------------------------
2256  PyObject* ReturnThree( ObjectProxy*, PyObject* ) {
2257  return PyInt_FromLong( 3 );
2258  }
2259 
2260  PyObject* ReturnTwo( ObjectProxy*, PyObject* ) {
2261  return PyInt_FromLong( 2 );
2262  }
2263 
2264 } // unnamed namespace
2265 
2266 
2267 //- public functions -----------------------------------------------------------
2268 Bool_t PyROOT::Pythonize( PyObject* pyclass, const std::string& name )
2269 {
2270 // Add pre-defined pythonizations (for STL and ROOT) to classes based on their
2271 // signature and/or class name.
2272  if ( pyclass == 0 )
2273  return kFALSE;
2274 
2275 //- method name based pythonization --------------------------------------------
2276 
2277 // for smart pointer style classes (note fall-through)
2278  if ( HasAttrDirect( pyclass, PyStrings::gDeref ) ) {
2279  Utility::AddToClass( pyclass, "__getattr__", (PyCFunction) DeRefGetAttr, METH_O );
2280  } else if ( HasAttrDirect( pyclass, PyStrings::gFollow ) ) {
2281  Utility::AddToClass( pyclass, "__getattr__", (PyCFunction) FollowGetAttr, METH_O );
2282  }
2283 
2284 // for STL containers, and user classes modeled after them
2285  if ( HasAttrDirect( pyclass, PyStrings::gSize ) )
2286  Utility::AddToClass( pyclass, "__len__", "size" );
2287 
2288 // like-wise, some typical container sizings
2289  if ( HasAttrDirect( pyclass, PyStrings::gGetSize ) )
2290  Utility::AddToClass( pyclass, "__len__", "GetSize" );
2291 
2292  if ( HasAttrDirect( pyclass, PyStrings::ggetSize ) )
2293  Utility::AddToClass( pyclass, "__len__", "getSize" );
2294 
2295  if ( HasAttrDirect( pyclass, PyStrings::gBegin ) && HasAttrDirect( pyclass, PyStrings::gEnd ) ) {
2296  // some classes may not have dicts for their iterators, making begin/end useless
2297  PyObject* pyfullname = PyObject_GetAttr( pyclass, PyStrings::gName );
2298  TClass* klass = TClass::GetClass( PyROOT_PyUnicode_AsString( pyfullname ) );
2299  Py_DECREF( pyfullname );
2300 
2301  if (!klass->InheritsFrom(TCollection::Class())) {
2302  // TCollection has a begin and end method so that they can be used in
2303  // the C++ range expression. However, unlike any other use of TIter,
2304  // TCollection::begin must include the first iteration. PyROOT is
2305  // handling TIter as a special case (as it should) and also does this
2306  // first iteration (via the first call to Next to get the first element)
2307  // and thus using begin in this case lead to the first element being
2308  // forgotten by PyROOT.
2309  // i.e. Don't search for begin in TCollection since we can not use.'
2310 
2311  TMethod* meth = klass->GetMethodAllAny( "begin" );
2312 
2313  TClass* iklass = 0;
2314  if ( meth ) {
2315  Int_t oldl = gErrorIgnoreLevel; gErrorIgnoreLevel = 3000;
2316  iklass = TClass::GetClass( meth->GetReturnTypeNormalizedName().c_str() );
2317  gErrorIgnoreLevel = oldl;
2318  }
2319 
2320  if ( iklass && iklass->GetClassInfo() ) {
2321  ((PyTypeObject*)pyclass)->tp_iter = (getiterfunc)StlSequenceIter;
2322  Utility::AddToClass( pyclass, "__iter__", (PyCFunction) StlSequenceIter, METH_NOARGS );
2323  } else if ( HasAttrDirect( pyclass, PyStrings::gGetItem ) && HasAttrDirect( pyclass, PyStrings::gLen ) ) {
2324  Utility::AddToClass( pyclass, "_getitem__unchecked", "__getitem__" );
2325  Utility::AddToClass( pyclass, "__getitem__", (PyCFunction) CheckedGetItem, METH_O );
2326  }
2327  }
2328  }
2329 
2330 // search for global comparator overloads (may fail; not sure whether it isn't better to
2331 // do this lazily just as is done for math operators, but this interplays nicely with the
2332 // generic versions)
2333  Utility::AddBinaryOperator( pyclass, "==", "__eq__" );
2334  Utility::AddBinaryOperator( pyclass, "!=", "__ne__" );
2335 
2336 // map operator==() through GenObjectIsEqual to allow comparison to None (kTRUE is to
2337 // require that the located method is a MethodProxy; this prevents circular calls as
2338 // GenObjectIsEqual is no MethodProxy)
2339  if ( HasAttrDirect( pyclass, PyStrings::gEq, kTRUE ) ) {
2340  Utility::AddToClass( pyclass, "__cpp_eq__", "__eq__" );
2341  Utility::AddToClass( pyclass, "__eq__", (PyCFunction) GenObjectIsEqual, METH_O );
2342  }
2343 
2344 // map operator!=() through GenObjectIsNotEqual to allow comparison to None (see note
2345 // on kTRUE above for __eq__)
2346  if ( HasAttrDirect( pyclass, PyStrings::gNe, kTRUE ) ) {
2347  Utility::AddToClass( pyclass, "__cpp_ne__", "__ne__" );
2348  Utility::AddToClass( pyclass, "__ne__", (PyCFunction) GenObjectIsNotEqual, METH_O );
2349  }
2350 
2351 
2352 //- class name based pythonization ---------------------------------------------
2353 
2354  if ( name == "TObject" ) {
2355  // support for the 'in' operator
2356  Utility::AddToClass( pyclass, "__contains__", (PyCFunction) TObjectContains, METH_O );
2357 
2358  // comparing for lists
2359  Utility::AddToClass( pyclass, "__cmp__", (PyCFunction) TObjectCompare, METH_O );
2360  Utility::AddToClass( pyclass, "__eq__", (PyCFunction) TObjectIsEqual, METH_O );
2361  Utility::AddToClass( pyclass, "__ne__", (PyCFunction) TObjectIsNotEqual, METH_O );
2362 
2363  }
2364 
2365  else if ( name == "TClass" ) {
2366  // make DynamicCast return a usable python object, rather than void*
2367  Utility::AddToClass( pyclass, "_TClass__DynamicCast", "DynamicCast" );
2368  Utility::AddToClass( pyclass, "DynamicCast", (PyCFunction) TClassDynamicCast );
2369 
2370  // the following cast is easier to use (reads both ways)
2371  Utility::AddToClass( pyclass, "StaticCast", (PyCFunction) TClassStaticCast );
2372 
2373  }
2374 
2375  else if ( name == "TCollection" ) {
2376  Utility::AddToClass( pyclass, "append", "Add" );
2377  Utility::AddToClass( pyclass, "extend", (PyCFunction) TCollectionExtend, METH_O );
2378  Utility::AddToClass( pyclass, "remove", (PyCFunction) TCollectionRemove, METH_O );
2379  Utility::AddToClass( pyclass, "__add__", (PyCFunction) TCollectionAdd, METH_O );
2380  Utility::AddToClass( pyclass, "__imul__", (PyCFunction) TCollectionIMul, METH_O );
2381  Utility::AddToClass( pyclass, "__mul__", (PyCFunction) TCollectionMul, METH_O );
2382  Utility::AddToClass( pyclass, "__rmul__", (PyCFunction) TCollectionMul, METH_O );
2383 
2384  Utility::AddToClass( pyclass, "count", (PyCFunction) TCollectionCount, METH_O );
2385 
2386  ((PyTypeObject*)pyclass)->tp_iter = (getiterfunc)TCollectionIter;
2387  Utility::AddToClass( pyclass, "__iter__", (PyCFunction)TCollectionIter, METH_NOARGS );
2388 
2389  }
2390 
2391  else if ( name == "TSeqCollection" ) {
2392  Utility::AddToClass( pyclass, "__getitem__", (PyCFunction) TSeqCollectionGetItem, METH_O );
2393  Utility::AddToClass( pyclass, "__setitem__", (PyCFunction) TSeqCollectionSetItem );
2394  Utility::AddToClass( pyclass, "__delitem__", (PyCFunction) TSeqCollectionDelItem, METH_O );
2395 
2396  Utility::AddToClass( pyclass, "insert", (PyCFunction) TSeqCollectionInsert );
2397  Utility::AddToClass( pyclass, "pop", (PyCFunction) TSeqCollectionPop );
2398  Utility::AddToClass( pyclass, "reverse", (PyCFunction) TSeqCollectionReverse, METH_NOARGS );
2399  Utility::AddToClass( pyclass, "sort", (PyCFunction) TSeqCollectionSort,
2400  METH_VARARGS | METH_KEYWORDS );
2401 
2402  Utility::AddToClass( pyclass, "index", (PyCFunction) TSeqCollectionIndex, METH_O );
2403 
2404  }
2405 
2406  else if ( name == "TObjArray" ) {
2407  Utility::AddToClass( pyclass, "__len__", (PyCFunction) TObjArrayLen, METH_NOARGS );
2408  }
2409 
2410  else if ( name == "TClonesArray" ) {
2411  // restore base TSeqCollection operator[] to prevent random object creation (it's
2412  // functionality is equivalent to the operator[](int) const of TClonesArray, but
2413  // there's no guarantee it'll be selected over the non-const version)
2414  Utility::AddToClass( pyclass, "__getitem__", (PyCFunction) TSeqCollectionGetItem, METH_O );
2415 
2416  // this setitem should be used with as much care as the C++ one
2417  Utility::AddToClass( pyclass, "__setitem__", (PyCFunction) TClonesArraySetItem );
2418 
2419  }
2420 
2421  else if ( IsTemplatedSTLClass( name, "vector" ) ) {
2422 
2423  if ( HasAttrDirect( pyclass, PyStrings::gLen ) && HasAttrDirect( pyclass, PyStrings::gAt ) ) {
2424  Utility::AddToClass( pyclass, "_vector__at", "at" );
2425  // remove iterator that was set earlier (checked __getitem__ will do the trick)
2426  if ( HasAttrDirect( pyclass, PyStrings::gIter ) )
2427  PyObject_DelAttr( pyclass, PyStrings::gIter );
2428  } else if ( HasAttrDirect( pyclass, PyStrings::gGetItem ) ) {
2429  Utility::AddToClass( pyclass, "_vector__at", "__getitem__" ); // unchecked!
2430  }
2431 
2432  // vector-optimized iterator protocol
2433  ((PyTypeObject*)pyclass)->tp_iter = (getiterfunc)vector_iter;
2434 
2435  // helpers for iteration
2436  TypedefInfo_t* ti = gInterpreter->TypedefInfo_Factory( (name+"::value_type").c_str() );
2437  if ( gInterpreter->TypedefInfo_IsValid( ti ) ) {
2438  PyObject* pyvalue_size = PyLong_FromLong( gInterpreter->TypedefInfo_Size( ti ) );
2439  PyObject_SetAttrString( pyclass, "value_size", pyvalue_size );
2440  Py_DECREF( pyvalue_size );
2441 
2442  PyObject* pyvalue_type = PyROOT_PyUnicode_FromString( gInterpreter->TypedefInfo_TrueName( ti ) );
2443  PyObject_SetAttrString( pyclass, "value_type", pyvalue_type );
2444  Py_DECREF( pyvalue_type );
2445  }
2446 
2447  // provide a slice-able __getitem__, if possible
2448  if ( HasAttrDirect( pyclass, PyStrings::gVectorAt ) )
2449  Utility::AddToClass( pyclass, "__getitem__", (PyCFunction) VectorGetItem, METH_O );
2450 
2451  // std::vector<bool> is a special case in C++
2452  std::string::size_type pos = name.find( "vector<bool" ); // to cover all variations
2453  if ( pos == 0 /* at beginning */ || pos == 5 /* after std:: */ ) {
2454  Utility::AddToClass( pyclass, "__setitem__", (PyCFunction) VectorBoolSetItem );
2455  }
2456 
2457  }
2458 
2459  else if ( IsTemplatedSTLClass( name, "map" ) ) {
2460  Utility::AddToClass( pyclass, "__contains__", (PyCFunction) MapContains, METH_O );
2461 
2462  }
2463 
2464  else if ( IsTemplatedSTLClass( name, "pair" ) ) {
2465  Utility::AddToClass( pyclass, "__getitem__", (PyCFunction) PairUnpack, METH_O );
2466  Utility::AddToClass( pyclass, "__len__", (PyCFunction) ReturnTwo, METH_NOARGS );
2467 
2468  }
2469 
2470  else if ( name.find( "iterator" ) != std::string::npos ) {
2471  ((PyTypeObject*)pyclass)->tp_iternext = (iternextfunc)StlIterNext;
2472  Utility::AddToClass( pyclass, "next", (PyCFunction) StlIterNext, METH_NOARGS );
2473 
2474  // special case, if operator== is a global overload and included in the dictionary
2475  if ( ! HasAttrDirect( pyclass, PyStrings::gCppEq, kTRUE ) )
2476  Utility::AddToClass( pyclass, "__eq__", (PyCFunction) StlIterIsEqual, METH_O );
2477  if ( ! HasAttrDirect( pyclass, PyStrings::gCppNe, kTRUE ) )
2478  Utility::AddToClass( pyclass, "__ne__", (PyCFunction) StlIterIsNotEqual, METH_O );
2479 
2480  }
2481 
2482  else if ( name == "string" || name == "std::string" ) {
2483  Utility::AddToClass( pyclass, "__repr__", (PyCFunction) StlStringRepr, METH_NOARGS );
2484  Utility::AddToClass( pyclass, "__str__", "c_str" );
2485  Utility::AddToClass( pyclass, "__cmp__", (PyCFunction) StlStringCompare, METH_O );
2486  Utility::AddToClass( pyclass, "__eq__", (PyCFunction) StlStringIsEqual, METH_O );
2487  Utility::AddToClass( pyclass, "__ne__", (PyCFunction) StlStringIsNotEqual, METH_O );
2488 
2489  }
2490 
2491  else if ( name == "TString" ) {
2492  Utility::AddToClass( pyclass, "__repr__", (PyCFunction) TStringRepr, METH_NOARGS );
2493  Utility::AddToClass( pyclass, "__str__", "Data" );
2494  Utility::AddToClass( pyclass, "__len__", "Length" );
2495 
2496  Utility::AddToClass( pyclass, "__cmp__", "CompareTo" );
2497  Utility::AddToClass( pyclass, "__eq__", (PyCFunction) TStringIsEqual, METH_O );
2498  Utility::AddToClass( pyclass, "__ne__", (PyCFunction) TStringIsNotEqual, METH_O );
2499 
2500  }
2501 
2502  else if ( name == "TObjString" ) {
2503  Utility::AddToClass( pyclass, "__repr__", (PyCFunction) TObjStringRepr, METH_NOARGS );
2504  Utility::AddToClass( pyclass, "__str__", "GetName" );
2505  Utility::AddToClass( pyclass, "__len__", (PyCFunction) TObjStringLength, METH_NOARGS );
2506 
2507  Utility::AddToClass( pyclass, "__cmp__", (PyCFunction) TObjStringCompare, METH_O );
2508  Utility::AddToClass( pyclass, "__eq__", (PyCFunction) TObjStringIsEqual, METH_O );
2509  Utility::AddToClass( pyclass, "__ne__", (PyCFunction) TObjStringIsNotEqual, METH_O );
2510 
2511  }
2512 
2513  else if ( name == "TIter" ) {
2514  ((PyTypeObject*)pyclass)->tp_iter = (getiterfunc)PyObject_SelfIter;
2515  Utility::AddToClass( pyclass, "__iter__", (PyCFunction) PyObject_SelfIter, METH_NOARGS );
2516 
2517  ((PyTypeObject*)pyclass)->tp_iternext = (iternextfunc)TIterNext;
2518  Utility::AddToClass( pyclass, "next", (PyCFunction) TIterNext, METH_NOARGS );
2519 
2520  }
2521 
2522  else if ( name == "TDirectory" ) {
2523  // note: this replaces the already existing TDirectory::GetObject()
2524  Utility::AddToClass( pyclass, "GetObject", (PyCFunction) TDirectoryGetObject );
2525 
2526  // note: this replaces the already existing TDirectory::WriteObject()
2527  Utility::AddToClass( pyclass, "WriteObject", (PyCFunction) TDirectoryWriteObject );
2528 
2529  }
2530 
2531  else if ( name == "TDirectoryFile" ) {
2532  // add safety for non-TObject derived Get() results
2533  Utility::AddToClass( pyclass, "Get", (PyCFunction) TDirectoryFileGet, METH_O );
2534 
2535  return kTRUE;
2536  }
2537 
2538  else if ( name == "TTree" ) {
2539  // allow direct browsing of the tree
2540  Utility::AddToClass( pyclass, "__getattr__", (PyCFunction) TTreeGetAttr, METH_O );
2541 
2542  // workaround for templated member Branch()
2543  MethodProxy* original =
2544  (MethodProxy*)PyObject_GetAttrFromDict( pyclass, PyStrings::gBranch );
2545  MethodProxy* method = MethodProxy_New( "Branch", new TTreeBranch( original ) );
2546  Py_DECREF( original ); original = 0;
2547 
2548  PyObject_SetAttrString(
2549  pyclass, const_cast< char* >( method->GetName().c_str() ), (PyObject*)method );
2550  Py_DECREF( method ); method = 0;
2551 
2552  // workaround for templated member SetBranchAddress()
2553  original = (MethodProxy*)PyObject_GetAttrFromDict( pyclass, PyStrings::gSetBranchAddress );
2554  method = MethodProxy_New( "SetBranchAddress", new TTreeSetBranchAddress( original ) );
2555  Py_DECREF( original ); original = 0;
2556 
2557  PyObject_SetAttrString(
2558  pyclass, const_cast< char* >( method->GetName().c_str() ), (PyObject*)method );
2559  Py_DECREF( method ); method = 0;
2560 
2561  }
2562 
2563  else if ( name == "TChain" ) {
2564  // allow SetBranchAddress to take object directly, w/o needing AddressOf()
2565  MethodProxy* original =
2566  (MethodProxy*)PyObject_GetAttrFromDict( pyclass, PyStrings::gSetBranchAddress );
2567  MethodProxy* method = MethodProxy_New( "SetBranchAddress", new TChainSetBranchAddress( original ) );
2568  Py_DECREF( original ); original = 0;
2569 
2570  PyObject_SetAttrString(
2571  pyclass, const_cast< char* >( method->GetName().c_str() ), (PyObject*)method );
2572  Py_DECREF( method ); method = 0;
2573 
2574  }
2575 
2576  else if ( name == "TStyle" ) {
2577  MethodProxy* ctor = (MethodProxy*)PyObject_GetAttr( pyclass, PyStrings::gInit );
2578  ctor->fMethodInfo->fFlags &= ~TCallContext::kIsCreator;
2579  Py_DECREF( ctor );
2580  }
2581 
2582  else if ( name == "TH1" ) // allow hist *= scalar
2583  Utility::AddToClass( pyclass, "__imul__", (PyCFunction) THNIMul, METH_O );
2584 
2585  else if ( name == "TF1" ) // allow instantiation with python callable
2586  Utility::AddToClass( pyclass, "__init__", new TF1InitWithPyFunc );
2587 
2588  else if ( name == "TF2" ) // allow instantiation with python callable
2589  Utility::AddToClass( pyclass, "__init__", new TF2InitWithPyFunc );
2590 
2591  else if ( name == "TF3" ) // allow instantiation with python callable
2592  Utility::AddToClass( pyclass, "__init__", new TF3InitWithPyFunc );
2593 
2594  else if ( name == "TFunction" ) // allow direct call
2595  Utility::AddToClass( pyclass, "__call__", (PyCFunction) TFunctionCall );
2596 
2597  else if ( name == "TMinuit" ) // allow call with python callable
2598  Utility::AddToClass( pyclass, "SetFCN", new TMinuitSetFCN );
2599 
2600  else if ( name == "TFitter" ) // allow call with python callable (this is not correct)
2601  Utility::AddToClass( pyclass, "SetFCN", new TMinuitFitterSetFCN );
2602 
2603  else if ( name == "Fitter" ) // really Fit::Fitter, allow call with python callable
2604  Utility::AddToClass( pyclass, "FitFCN", new TFitterFitFCN );
2605 
2606  else if ( name == "TFile" ) {
2607  // TFile::Open really is a constructor, really
2608  PyObject* attr = PyObject_GetAttrString( pyclass, (char*)"Open" );
2609  if ( MethodProxy_Check( attr ) )
2610  ((MethodProxy*)attr)->fMethodInfo->fFlags |= TCallContext::kIsCreator;
2611  Py_XDECREF( attr );
2612 
2613  // allow member-style access to entries in file
2614  Utility::AddToClass( pyclass, "__getattr__", (PyCFunction) TFileGetAttr, METH_O );
2615 
2616  }
2617 
2618  else if ( name.substr(0,8) == "TVector3" ) {
2619  Utility::AddToClass( pyclass, "__len__", (PyCFunction) ReturnThree, METH_NOARGS );
2620  Utility::AddToClass( pyclass, "_getitem__unchecked", "__getitem__" );
2621  Utility::AddToClass( pyclass, "__getitem__", (PyCFunction) CheckedGetItem, METH_O );
2622 
2623  }
2624 
2625  else if ( name.substr(0,8) == "TVectorT" ) { // allow proper iteration
2626  Utility::AddToClass( pyclass, "__len__", "GetNoElements" );
2627  Utility::AddToClass( pyclass, "_getitem__unchecked", "__getitem__" );
2628  Utility::AddToClass( pyclass, "__getitem__", (PyCFunction) CheckedGetItem, METH_O );
2629 
2630  }
2631 
2632  else if ( name.substr(0,6) == "TArray" ) { // allow proper iteration
2633  // __len__ is already set from GetSize()
2634  Utility::AddToClass( pyclass, "_getitem__unchecked", "__getitem__" );
2635  Utility::AddToClass( pyclass, "__getitem__", (PyCFunction) CheckedGetItem, METH_O );
2636  }
2637 
2638 // Make RooFit 'using' member functions available (not supported by dictionary)
2639  else if ( name == "RooDataHist" )
2640  Utility::AddUsingToClass( pyclass, "plotOn" );
2641 
2642  else if ( name == "RooSimultaneous" )
2643  Utility::AddUsingToClass( pyclass, "plotOn" );
2644 
2645 
2646 // TODO: store these on the pythonizations module, nog on gRootModule
2647 // TODO: externalize this code and use update handlers on the python side
2648  PyObject* userPythonizations = PyObject_GetAttrString( gRootModule, "UserPythonizations" );
2649  PyObject* pythonizationScope = PyObject_GetAttrString( gRootModule, "PythonizationScope" );
2650 
2651  std::vector< std::string > pythonization_scopes;
2652  pythonization_scopes.push_back( "__global__" );
2653 
2654  std::string user_scope = PyROOT_PyUnicode_AsString( pythonizationScope );
2655  if ( user_scope != "__global__" ) {
2656  if ( PyDict_Contains( userPythonizations, pythonizationScope ) ) {
2657  pythonization_scopes.push_back( user_scope );
2658  }
2659  }
2660 
2661  Bool_t pstatus = kTRUE;
2662 
2663  for ( auto key = pythonization_scopes.cbegin(); key != pythonization_scopes.cend(); ++key ) {
2664  PyObject* tmp = PyDict_GetItemString( userPythonizations, key->c_str() );
2665  Py_ssize_t num_pythonizations = PyList_Size( tmp );
2666  PyObject* arglist = nullptr;
2667  if ( num_pythonizations )
2668  arglist = Py_BuildValue( "O,s", pyclass, name.c_str() );
2669  for ( Py_ssize_t i = 0; i < num_pythonizations; ++i ) {
2670  PyObject* pythonizor = PyList_GetItem( tmp, i );
2671  // TODO: detail error handling for the pythonizors
2672  PyObject* result = PyObject_CallObject( pythonizor, arglist );
2673  if ( !result ) {
2674  pstatus = kFALSE;
2675  break;
2676  } else
2677  Py_DECREF( result );
2678  }
2679  Py_XDECREF( arglist );
2680  }
2681 
2682  Py_DECREF( userPythonizations );
2683  Py_DECREF( pythonizationScope );
2684 
2685 
2686 // phew! all done ...
2687  return pstatus;
2688 }
R__EXTERN PyObject * gFirst
Definition: PyStrings.h:45
R__EXTERN PyObject * gCppEq
Definition: PyStrings.h:19
virtual void Add(TObject *obj)
A TLeaf describes individual elements of a TBranch See TBranch structure in TTree.
Definition: TLeaf.h:37
TCppScope_t TCppType_t
Definition: Cppyy.h:13
Bool_t AddBinaryOperator(PyObject *left, PyObject *right, const char *op, const char *label, const char *alt_label=NULL)
Install the named operator (op) into the left object's class if such a function exists as a global ov...
Definition: Utility.cxx:315
R__EXTERN PyObject * gInit
Definition: PyStrings.h:27
#define PyROOT_PyUnicode_FromString
Definition: PyROOT.h:71
R__EXTERN PyObject * gIter
Definition: PyStrings.h:28
An array of TObjects.
Definition: TObjArray.h:39
R__EXTERN PyObject * gDict
Definition: PyStrings.h:22
R__EXTERN PyObject * gEq
Definition: PyStrings.h:24
Int_t GetID() const
R__EXTERN PyObject * gGetSize
Definition: PyStrings.h:48
virtual TLeaf * GetLeaf(const char *name) const
Return pointer to the 1st Leaf named name in thisBranch.
Definition: TBranch.cxx:1460
R__EXTERN Int_t gErrorIgnoreLevel
Definition: TError.h:107
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:487
virtual TClass * GetTargetClass()
ClassImp(TSeqCollection) Int_t TSeqCollection TIter next(this)
Return index of object in collection.
Ssiz_t Length() const
Definition: TString.h:390
Collectable string class.
Definition: TObjString.h:32
static Bool_t RegisterObject(ObjectProxy *pyobj, TObject *object)
start tracking <object> proxied by <pyobj>
tuple offset
Definition: tree.py:93
char * GetObject() const
Return a pointer to our object.
R__EXTERN PyObject * gTClassDynCast
Definition: PyStrings.h:58
R__EXTERN PyObject * gSize
Definition: PyStrings.h:47
virtual TLeaf * GetLeaf(const char *branchname, const char *leafname)
Return pointer to the 1st Leaf named name in any Branch of this Tree or any branch in the list of fri...
Definition: TTree.cxx:5520
R__EXTERN PyObject * gFollow
Definition: PyStrings.h:25
virtual TObject * Get(const char *namecycle)
Return pointer to object identified by namecycle.
virtual TKey * GetKey(const char *name, Short_t cycle=9999) const
Return pointer to key with name,cycle.
MethodProxy * MethodProxy_New(const std::string &name, std::vector< PyCallable * > &methods)
Definition: MethodProxy.h:75
R__EXTERN PyObject * gSetFCN
Definition: PyStrings.h:57
std::string GetFinalName(TCppType_t type)
Definition: Cppyy.cxx:534
R__EXTERN PyObject * gBranch
Definition: PyStrings.h:53
Basic string class.
Definition: TString.h:137
std::vector< PyCallable * > Methods_t
Definition: MethodProxy.h:24
R__EXTERN PyObject * gFitFCN
Definition: PyStrings.h:54
virtual const char * GetClassName() const
Definition: TKey.h:77
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
R__EXTERN PyObject * gEnd
Definition: PyStrings.h:44
const Bool_t kFALSE
Definition: Rtypes.h:92
#define gInterpreter
Definition: TInterpreter.h:502
TBranch * GetBranch() const
Definition: TLeaf.h:70
#define PYROOT_IMPLEMENT_STRING_PYTHONIZATION(type, name)
Definition: Pythonize.cxx:1155
R__EXTERN PyObject * gCppNe
Definition: PyStrings.h:20
PyObject * TTreeGetAttr(ObjectProxy *self, PyObject *pyname)
Definition: Pythonize.cxx:1383
std::string GetReturnTypeNormalizedName() const
Get the normalized name of the return type.
Definition: TFunction.cxx:154
R__EXTERN PyObject * gVectorAt
Definition: PyStrings.h:51
#define PyInt_FromSsize_t
Definition: PyROOT.h:156
TMethod * GetMethodAllAny(const char *method)
Return pointer to method without looking at parameters.
Definition: TClass.cxx:4037
R__EXTERN PyObject * gDeref
Definition: PyStrings.h:21
virtual Int_t GetNdata() const
Definition: TLeaf.h:78
virtual TObject * RemoveAt(Int_t idx)
virtual void * GetObjectChecked(const char *namecycle, const char *classname)
See documentation of TDirectory::GetObjectCheck(const char *namecycle, const TClass *cl) ...
Definition: TDirectory.cxx:790
#define PyVarObject_HEAD_INIT(type, size)
Definition: PyROOT.h:147
TTree * T
const char * Data() const
Definition: TString.h:349
Sequenceable collection abstract base class.
MethodProxy::Methods_t fMethods
Definition: MethodProxy.h:32
virtual Int_t SetBranchAddress(const char *bname, void *add, TBranch **ptr=0)
Change branch address, dealing with clone trees properly.
Definition: TTree.cxx:7510
R__EXTERN PyObject * gRootModule
Definition: ObjectProxy.cxx:40
void Class()
Definition: Class.C:29
TStreamerInfo * GetInfo() const
Get streamer info for the branch class.
int d
Definition: tornado.py:11
void * New(ENewType defConstructor=kClassNew, Bool_t quiet=kFALSE) const
Return a pointer to a newly allocated object of this class.
Definition: TClass.cxx:4602
std::map< std::string, std::string >::const_iterator iter
Definition: TAlienJob.cxx:54
virtual PyObject * FromMemory(void *address)
Definition: Converters.cxx:41
virtual Int_t WriteObjectAny(const void *, const char *, const char *, Option_t *="", Int_t=0)
Definition: TDirectory.h:208
R__EXTERN PyObject * gAt
Definition: PyStrings.h:42
const std::string ClassName(PyObject *pyobj)
Retrieve the class name from the given python object (which may be just an instance of the class)...
Definition: Utility.cxx:694
#define PyROOT_PyUnicode_Type
Definition: PyROOT.h:77
#define PyROOT_PyUnicode_AsString
Definition: PyROOT.h:66
TObject * First() const
Return the object in the first slot.
Definition: TObjArray.cxx:471
Book space in a file, create I/O buffers, to fill them, (un)compress them.
Definition: TKey.h:30
virtual TObject * RemoveAt(Int_t idx)
Remove object at index idx.
#define PyROOT_PySliceCast
Definition: PyROOT.h:142
Cppyy::TCppType_t ObjectIsA() const
Definition: ObjectProxy.h:66
virtual TBranch * GetBranch(const char *name)
Return pointer to the branch with the given name in this tree or its friends.
Definition: TTree.cxx:4803
TConverter * CreateConverter(const std::string &fullType, Long_t size=-1)
PyTypeObject ObjectProxy_Type
virtual char * GetAddress() const
Definition: TBranch.h:146
ptrdiff_t TCppMethod_t
Definition: Cppyy.h:15
Bool_t ObjectProxy_Check(T *object)
Definition: ObjectProxy.h:91
R__EXTERN PyObject * gClass
Definition: PyStrings.h:18
R__EXTERN PyObject * gBegin
Definition: PyStrings.h:43
virtual const char * GetTypeName() const
Definition: TLeaf.h:81
TCppScope_t gGlobalScope
Definition: Cppyy.cxx:58
TString GetString() const
Definition: TObjString.h:50
TObjArray * GetElements() const
#define PyInt_AsSsize_t
Definition: PyROOT.h:155
SVector< double, 2 > v
Definition: Dict.h:5
A ROOT file is structured in Directories (like a file system).
ClassInfo_t * GetClassInfo() const
Definition: TClass.h:390
Collection abstract base class.
Definition: TCollection.h:48
virtual const char * GetAlias(const char *aliasName) const
Returns the expanded value of the alias. Search in the friends if any.
Definition: TTree.cxx:4762
#define PyROOT_PyUnicode_FromStringAndSize
Definition: PyROOT.h:75
TClass * GetCurrentClass()
Return a pointer to the current type of the data member corresponding to branch element.
PyObject * BindCppObjectNoCast(Cppyy::TCppObject_t object, Cppyy::TCppType_t klass, Bool_t isRef=kFALSE, Bool_t isValue=kFALSE)
only known or knowable objects will be bound (null object is ok)
TLine * l
Definition: textangle.C:4
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
The ROOT global object gROOT contains a list of all defined classes.
Definition: TClass.h:81
virtual TLeaf * GetLeafCount() const
Definition: TLeaf.h:71
PyObject * PyBuffer_FromMemory(Bool_t *buf, Py_ssize_t size=-1)
A Branch for the case of an object.
TEllipse dict(9, 20, 3, 1.5)
long Long_t
Definition: RtypesCore.h:50
MethodInfo_t * fMethodInfo
Definition: MethodProxy.h:52
virtual Int_t GetSize() const
Definition: TCollection.h:95
virtual PyObject * Call(ObjectProxy *&self, PyObject *args, PyObject *kwds, TCallContext *ctxt=0)=0
PyObject * CreateScopeProxy(Cppyy::TCppScope_t)
Convenience function with a lookup first through the known existing proxies.
R__EXTERN PyObject * gGetItem
Definition: PyStrings.h:26
TCppScope_t GetScope(const std::string &scope_name)
Definition: Cppyy.cxx:150
double Double_t
Definition: RtypesCore.h:55
R__EXTERN PyObject * gName
Definition: PyStrings.h:33
TClass * GetClass() const
Definition: TClonesArray.h:57
Describe directory structure in memory.
Definition: TDirectory.h:44
static TClass * OP2TCLASS(PyROOT::ObjectProxy *pyobj)
Definition: Pythonize.cxx:55
R__EXTERN PyObject * gLen
Definition: PyStrings.h:29
Bool_t AddToClass(PyObject *pyclass, const char *label, PyCFunction cfunc, int flags=METH_VARARGS)
Add the given function to the class under name 'label'.
Definition: Utility.cxx:186
#define PyROOT_PyUnicode_Check
Definition: PyROOT.h:64
TObjArray * GetListOfLeaves()
Definition: TBranch.h:178
virtual void * GetObjectChecked(const char *namecycle, const char *classname)
See documentation of TDirectoryFile::GetObjectCheck(const char *namecycle, const TClass *cl) ...
virtual void AddAt(TObject *obj, Int_t idx)=0
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition: TClass.cxx:2801
#define PYROOT_IMPLEMENT_STRING_PYTHONIZATION_CMP(type, name)
Definition: Pythonize.cxx:1204
R__EXTERN PyObject * gNe
Definition: PyStrings.h:34
Bool_t AddUsingToClass(PyObject *pyclass, const char *method)
Helper to add base class methods to the derived class one (this covers the 'using' cases...
Definition: Utility.cxx:261
#define name(a, b)
Definition: linkTestLib0.cpp:5
Binding & operator=(OUT(*fun)(void))
virtual TObject * At(Int_t idx) const =0
#define org(otri, vertexptr)
Definition: triangle.c:1037
Mother of all ROOT objects.
Definition: TObject.h:58
virtual Int_t Branch(TCollection *list, Int_t bufsize=32000, Int_t splitlevel=99, const char *name="")
Create one branch for each element in the collection.
Definition: TTree.cxx:1623
#define R__EXTERN
Definition: DllImport.h:27
const std::string & GetName() const
Definition: MethodProxy.h:45
void * GetObject() const
Definition: ObjectProxy.h:47
TObject * Last() const
Return the object in the last filled slot. Returns 0 if no entries.
Definition: TObjArray.cxx:479
An array of clone (identical) objects.
Definition: TClonesArray.h:32
#define Py_TYPE(ob)
Definition: PyROOT.h:149
int Py_ssize_t
Definition: PyROOT.h:154
virtual void * GetValuePointer() const
Definition: TLeaf.h:80
static TPyBufferFactory * Instance()
R__EXTERN PyObject * gSecond
Definition: PyStrings.h:46
virtual Int_t GetLenStatic() const
Definition: TLeaf.h:74
int GetBuffer(PyObject *pyobject, char tc, int size, void *&buf, Bool_t check=kTRUE)
Retrieve a linear buffer pointer from the given pyobject.
Definition: Utility.cxx:536
PyObject * GetScopeProxy(Cppyy::TCppScope_t)
Retrieve scope proxy from the known ones.
Each ROOT class (see TClass) has a linked list of methods.
Definition: TMethod.h:40
void * CreateWrapperMethod(PyObject *pyfunc, Long_t user, const char *retType, const std::vector< std::string > &signature, const char *callback)
Compile a function on the fly and return a function pointer for use on C-APIs.
Definition: Utility.cxx:820
Bool_t MethodProxy_Check(T *object)
Definition: MethodProxy.h:63
#define NULL
Definition: Rtypes.h:82
void * GetObject() const
double TFNPyCallback(void *vpyfunc, Long_t npar, double *a0, double *a1)
Definition: Pythonize.cxx:1777
R__EXTERN PyObject * ggetSize
Definition: PyStrings.h:49
A TTree object has a header with a name and a title.
Definition: TTree.h:98
double result[121]
void * DynamicCast(const TClass *base, void *obj, Bool_t up=kTRUE)
Cast obj of this class type up to baseclass cl if up is true.
Definition: TClass.cxx:4539
TCppObject_t Construct(TCppType_t type)
Definition: Cppyy.cxx:239
Bool_t InheritsFrom(const char *cl) const
Return kTRUE if this class inherits from a class with name "classname".
Definition: TClass.cxx:4498
TObject * At(Int_t idx) const
Definition: TObjArray.h:167
static PyObject * PyROOT_PyCapsule_New(void *cobj, const char *, void(*destr)(void *))
Definition: PyROOT.h:79
R__EXTERN PyObject * gSetBranchAddress
Definition: PyStrings.h:56
A TTree is a list of TBranches.
Definition: TBranch.h:58
virtual const char * GetClassName() const
Return the name of the user class whose content is stored in this branch, if any. ...
Definition: TBranch.cxx:1166
const Bool_t kTRUE
Definition: Rtypes.h:91
float value
Definition: math.cpp:443
void TMinuitPyCallback(void *vpyfunc, Long_t, Int_t &a0, Double_t *a1, Double_t &a2, Double_t *a3, Int_t a4)
Definition: Pythonize.cxx:1747
PyObject * BindCppObject(Cppyy::TCppObject_t object, Cppyy::TCppType_t klass, Bool_t isRef=kFALSE)
if the object is a null pointer, return a typed one (as needed for overloading)
void Set(void *address, EFlags flags=kNone)
Definition: ObjectProxy.h:33
Int_t Size() const
Return size of object of this class.
Definition: TClass.cxx:5243
_object PyObject
Definition: TPyArg.h:22
Bool_t Pythonize(PyObject *pyclass, const std::string &name)
Definition: Pythonize.cxx:2268