ROOT  6.07/01
Reference Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Executors.cxx
Go to the documentation of this file.
1 // @(#)root/pyroot:$Id$
2 // Author: Wim Lavrijsen, Jan 2005
3 
4 // Bindings
5 #include "PyROOT.h"
6 #include "PyStrings.h"
7 #include "Executors.h"
8 #include "ObjectProxy.h"
9 #include "TPyBufferFactory.h"
10 #include "RootWrapper.h"
11 #include "Utility.h"
12 
13 // ROOT
14 #include "TClassEdit.h" // for ShortType and CleanType
15 
16 // Standard
17 #include <cstring>
18 #include <utility>
19 #include <sstream>
20 
21 
22 //- data ______________________________________________________________________
23 namespace PyROOT {
24 
25  typedef TExecutor* (*ExecutorFactory_t) ();
26  typedef std::map< std::string, ExecutorFactory_t > ExecFactories_t;
28 
30 }
31 
32 
33 //- helpers -------------------------------------------------------------------
34 namespace {
35 
36  class GILControl {
37  public:
38  GILControl( PyROOT::TCallContext* ctxt ) :
39  fSave( nullptr ), fRelease( ReleasesGIL( ctxt ) ) {
40 #ifdef WITH_THREAD
41  if ( fRelease ) fSave = PyEval_SaveThread();
42 #endif
43  }
44  ~GILControl() {
45 #ifdef WITH_THREAD
46  if ( fRelease ) PyEval_RestoreThread( fSave );
47 #endif
48  }
49  private:
50  PyThreadState* fSave;
51  Bool_t fRelease;
52  };
53 
54 } // unnamed namespace
55 
56 #define PYROOT_IMPL_GILCALL( rtype, tcode ) \
57 static inline rtype GILCall##tcode( \
58  Cppyy::TCppMethod_t method, Cppyy::TCppObject_t self, PyROOT::TCallContext* ctxt ) {\
59  GILControl gc( ctxt ); \
60  return Cppyy::Call##tcode( method, self, &ctxt->fArgs ); \
61 }
62 
63 PYROOT_IMPL_GILCALL( void, V )
66 //PYROOT_IMPL_GILCALL( Short_t, H )
73 PYROOT_IMPL_GILCALL( void*, R )
74 PYROOT_IMPL_GILCALL( Char_t*, S )
75 
76 static inline Cppyy::TCppObject_t GILCallO( Cppyy::TCppMethod_t method,
77  Cppyy::TCppObject_t self, PyROOT::TCallContext* ctxt, Cppyy::TCppType_t klass ) {
78  GILControl gc( ctxt );
79  return Cppyy::CallO( method, self, &ctxt->fArgs, klass );
80 }
81 
84  GILControl gc( ctxt );
85  return Cppyy::CallConstructor( method, klass, &ctxt->fArgs );
86 }
87 
89  if ( c < 0 ) return PyInt_FromLong( c ); // python chars are range(256)
90  return PyROOT_PyUnicode_FromFormat( "%c", c );
91 }
92 
93 static inline PyObject* PyROOT_PyBool_FromInt( Int_t b ) {
94  PyObject* result = (Bool_t)b ? Py_True : Py_False;
95  Py_INCREF( result );
96  return result;
97 }
98 
99 
100 //- executors for built-ins ---------------------------------------------------
101 PyObject* PyROOT::TBoolExecutor::Execute(
103 {
104 // execute <method> with argument <self, ctxt>, construct python bool return value
105  Bool_t retval = GILCallB( method, self, ctxt );
106  PyObject* result = retval ? Py_True : Py_False;
107  Py_INCREF( result );
108  return result;
109 }
110 
111 ////////////////////////////////////////////////////////////////////////////////
112 /// execute <method> with argument <self, ctxt>, construct python bool return value
113 
114 PyObject* PyROOT::TBoolConstRefExecutor::Execute(
116 {
117  return PyROOT_PyBool_FromInt( *((Bool_t*)GILCallR( method, self, ctxt )) );
118 }
119 
120 ////////////////////////////////////////////////////////////////////////////////
121 /// execute <method with argument <self, ctxt>, construct python string return value
122 /// with the single char
123 
124 PyObject* PyROOT::TCharExecutor::Execute(
126 {
127  return PyROOT_PyUnicode_FromInt( (Int_t)GILCallC( method, self, ctxt ) );
128 }
129 
130 ////////////////////////////////////////////////////////////////////////////////
131 /// execute <method> with argument <self, ctxt>, construct python string return value
132 /// with the single char
133 
134 PyObject* PyROOT::TCharConstRefExecutor::Execute(
136 {
137  return PyROOT_PyUnicode_FromInt( *((Char_t*)GILCallR( method, self, ctxt )) );
138 }
139 
140 ////////////////////////////////////////////////////////////////////////////////
141 /// execute <method> with argument <self, args>, construct python string return value
142 /// with the single char
143 
144 PyObject* PyROOT::TUCharExecutor::Execute(
146 {
147  return PyROOT_PyUnicode_FromInt( (UChar_t)GILCallB( method, self, ctxt ) );
148 }
149 
150 ////////////////////////////////////////////////////////////////////////////////
151 /// execute <method> with argument <self, ctxt>, construct python string return value
152 /// with the single char from the pointer return
153 
154 PyObject* PyROOT::TUCharConstRefExecutor::Execute(
156 {
157  return PyROOT_PyUnicode_FromInt( *((UChar_t*)GILCallR( method, self, ctxt )) );
158 }
159 
160 ////////////////////////////////////////////////////////////////////////////////
161 /// execute <method> with argument <self, ctxt>, construct python int return value
162 
163 PyObject* PyROOT::TIntExecutor::Execute(
165 {
166  return PyInt_FromLong( (Int_t)GILCallI( method, self, ctxt ) );
167 }
168 
169 ////////////////////////////////////////////////////////////////////////////////
170 /// execute <method> with argument <self, ctxt>, construct python long return value
171 
172 PyObject* PyROOT::TLongExecutor::Execute(
174 {
175  return PyLong_FromLong( (Long_t)GILCallL( method, self, ctxt ) );
176 }
177 
178 ////////////////////////////////////////////////////////////////////////////////
179 /// execute <method> with argument <self, ctxt>, construct python unsigned long return value
180 
181 PyObject* PyROOT::TULongExecutor::Execute(
183 {
184  return PyLong_FromUnsignedLong( (ULong_t)GILCallLL( method, self, ctxt ) );
185 }
186 
187 ////////////////////////////////////////////////////////////////////////////////
188 /// execute <method> with argument <self, ctxt>, construct python long long return value
189 
190 PyObject* PyROOT::TLongLongExecutor::Execute(
192 {
193  Long64_t result = GILCallLL( method, self, ctxt );
194  return PyLong_FromLongLong( result );
195 }
196 
197 ////////////////////////////////////////////////////////////////////////////////
198 /// execute <method> with argument <self, ctxt>, construct python unsigned long long return value
199 
200 PyObject* PyROOT::TULongLongExecutor::Execute(
202 {
203  ULong64_t result = (ULong64_t)GILCallLL( method, self, ctxt );
204  return PyLong_FromUnsignedLongLong( result );
205 }
206 
207 ////////////////////////////////////////////////////////////////////////////////
208 /// execute <method> with argument <self, ctxt>, construct python float return value
209 
210 PyObject* PyROOT::TFloatExecutor::Execute(
212 {
213  return PyFloat_FromDouble( (Double_t)GILCallF( method, self, ctxt ) );
214 }
215 
216 ////////////////////////////////////////////////////////////////////////////////
217 /// execute <method> with argument <self, ctxt>, construct python float return value
218 
219 PyObject* PyROOT::TDoubleExecutor::Execute(
221 {
222  return PyFloat_FromDouble( (Double_t)GILCallD( method, self, ctxt ) );
223 }
224 
225 ////////////////////////////////////////////////////////////////////////////////
226 /// execute <method> with argument <self, ctxt>, construct python float return value
227 
228 PyObject* PyROOT::TLongDoubleExecutor::Execute(
230 {
231  return PyFloat_FromDouble( (Double_t)GILCallLD( method, self, ctxt ) );
232 }
233 
234 ////////////////////////////////////////////////////////////////////////////////
235 /// prepare "buffer" for by-ref returns, used with __setitem__
236 
238 {
239  if ( pyobject != 0 ) {
240  Py_INCREF( pyobject );
241  fAssignable = pyobject;
242  return kTRUE;
243  }
244 
245  fAssignable = 0;
246  return kFALSE;
247 }
248 
249 ////////////////////////////////////////////////////////////////////////////////
250 
251 #define PYROOT_IMPLEMENT_BASIC_REFEXECUTOR( name, type, stype, F1, F2 ) \
252 PyObject* PyROOT::T##name##RefExecutor::Execute( \
253  Cppyy::TCppMethod_t method, Cppyy::TCppObject_t self, TCallContext* ctxt )\
254 { \
255  type* ref = (type*)GILCallR( method, self, ctxt ); \
256  if ( ! fAssignable ) \
257  return F1( (stype)*ref ); \
258  else { \
259  *ref = (type)F2( fAssignable ); \
260  Py_DECREF( fAssignable ); \
261  fAssignable = 0; \
262  Py_INCREF( Py_None ); \
263  return Py_None; \
264  } \
265 }
266 
270 PYROOT_IMPLEMENT_BASIC_REFEXECUTOR( Short, Short_t, Long_t, PyInt_FromLong, PyLong_AsLong )
272 PYROOT_IMPLEMENT_BASIC_REFEXECUTOR( Int, Int_t, Long_t, PyInt_FromLong, PyLong_AsLong )
273 PYROOT_IMPLEMENT_BASIC_REFEXECUTOR( UInt, UInt_t, ULong_t, PyLong_FromUnsignedLong, PyLongOrInt_AsULong )
274 PYROOT_IMPLEMENT_BASIC_REFEXECUTOR( Long, Long_t, Long_t, PyLong_FromLong, PyLong_AsLong )
275 PYROOT_IMPLEMENT_BASIC_REFEXECUTOR( ULong, ULong_t, ULong_t, PyLong_FromUnsignedLong, PyLongOrInt_AsULong )
277  LongLong, Long64_t, Long64_t, PyLong_FromLongLong, PyLong_AsLongLong )
280 PYROOT_IMPLEMENT_BASIC_REFEXECUTOR( Float, Float_t, Double_t, PyFloat_FromDouble, PyFloat_AsDouble )
281 PYROOT_IMPLEMENT_BASIC_REFEXECUTOR( Double, Double_t, Double_t, PyFloat_FromDouble, PyFloat_AsDouble )
283  LongDouble, LongDouble_t, LongDouble_t, PyFloat_FromDouble, PyFloat_AsDouble )
284 
285 ////////////////////////////////////////////////////////////////////////////////
286 /// execute <method> with argument <self, ctxt>, return python string return value
287 
288 PyObject* PyROOT::TSTLStringRefExecutor::Execute(
289  Cppyy::TCppMethod_t method, Cppyy::TCppObject_t self, TCallContext* ctxt )
290 {
291  if ( ! fAssignable ) {
292  std::string* result = (std::string*)GILCallR( method, self, ctxt );
293  return PyROOT_PyUnicode_FromStringAndSize( result->c_str(), result->size() );
294  } else {
295  std::string* result = (std::string*)GILCallR( method, self, ctxt );
296  *result = std::string(
297  PyROOT_PyUnicode_AsString( fAssignable ), PyROOT_PyUnicode_GET_SIZE( fAssignable ) );
298 
299  Py_DECREF( fAssignable );
300  fAssignable = 0;
301 
302  Py_INCREF( Py_None );
303  return Py_None;
304  }
305 }
306 
307 ////////////////////////////////////////////////////////////////////////////////
308 /// execute <method> with argument <self, ctxt>, return None
309 
310 PyObject* PyROOT::TVoidExecutor::Execute(
312 {
313  GILCallV( method, self, ctxt );
314  Py_INCREF( Py_None );
315  return Py_None;
316 }
317 
318 ////////////////////////////////////////////////////////////////////////////////
319 /// execute <method> with argument <self, ctxt>, construct python string return value
320 
321 PyObject* PyROOT::TCStringExecutor::Execute(
323 {
324  char* result = (char*)GILCallS( method, self, ctxt );
325  if ( ! result ) {
326  Py_INCREF( PyStrings::gEmptyString );
328  }
329 
330  return PyROOT_PyUnicode_FromString( result );
331 }
332 
333 
334 //- pointer/array executors ---------------------------------------------------
335 PyObject* PyROOT::TVoidArrayExecutor::Execute(
337 {
338 // execute <method> with argument <self, ctxt>, construct python long return value
339  Long_t* result = (Long_t*)GILCallR( method, self, ctxt );
340  if ( ! result ) {
341  Py_INCREF( gNullPtrObject );
342  return gNullPtrObject;
343  }
344  return BufFac_t::Instance()->PyBuffer_FromMemory( result, 1 );
345 }
346 
347 ////////////////////////////////////////////////////////////////////////////////
348 
349 #define PYROOT_IMPLEMENT_ARRAY_EXECUTOR( name, type ) \
350 PyObject* PyROOT::T##name##ArrayExecutor::Execute( \
351  Cppyy::TCppMethod_t method, Cppyy::TCppObject_t self, TCallContext* ctxt )\
352 { \
353  return BufFac_t::Instance()->PyBuffer_FromMemory( (type*)GILCallR( method, self, ctxt ) );\
354 }
355 
365 
366 
367 //- special cases ------------------------------------------------------------
368 PyObject* PyROOT::TSTLStringExecutor::Execute(
369  Cppyy::TCppMethod_t method, Cppyy::TCppObject_t self, TCallContext* ctxt )
370 {
371 // execute <method> with argument <self, ctxt>, construct python string return value
372 
373  static Cppyy::TCppScope_t sSTLStringScope = Cppyy::GetScope( "std::string" );
374  std::string* result = (std::string*)GILCallO( method, self, ctxt, sSTLStringScope );
375  if ( ! result ) {
376  Py_INCREF( PyStrings::gEmptyString );
378  }
379 
380  PyObject* pyresult =
381  PyROOT_PyUnicode_FromStringAndSize( result->c_str(), result->size() );
382  delete result;
383 
384  return pyresult;
385 }
386 
387 ////////////////////////////////////////////////////////////////////////////////
388 /// execute <method> with argument <self, ctxt>, construct python proxy object return value
389 
390 PyObject* PyROOT::TTGlobalExecutor::Execute(
392 {
393  return BindCppGlobal( (TGlobal*)GILCallR( method, self, ctxt ) );
394 }
395 
396 ////////////////////////////////////////////////////////////////////////////////
397 /// execute <method> with argument <self, ctxt>, construct python proxy object return value
398 
401 {
402  return BindCppObject( (void*)GILCallR( method, self, ctxt ), fClass );
403 }
404 
405 ////////////////////////////////////////////////////////////////////////////////
406 /// execution will bring a temporary in existence
407 
410 {
411  Cppyy::TCppObject_t value = GILCallO( method, self, ctxt, fClass );
412 
413  if ( ! value ) {
414  if ( ! PyErr_Occurred() ) // callee may have set a python error itself
415  PyErr_SetString( PyExc_ValueError, "NULL result where temporary expected" );
416  return 0;
417  }
418 
419 // the result can then be bound
421  if ( ! pyobj )
422  return 0;
423 
424 // python ref counting will now control this object's life span
425  pyobj->HoldOn();
426  return (PyObject*)pyobj;
427 }
428 
429 
430 ////////////////////////////////////////////////////////////////////////////////
431 /// executor binds the result to the left-hand side, overwriting if an old object
432 
435 {
436  PyObject* result = BindCppObject( (void*)GILCallR( method, self, ctxt ), fClass );
437  if ( ! result || ! fAssignable )
438  return result;
439  else {
440  // this generic code is quite slow compared to its C++ equivalent ...
441  PyObject* assign = PyObject_GetAttrString( result, const_cast< char* >( "__assign__" ) );
442  if ( ! assign ) {
443  PyErr_Clear();
444  PyObject* descr = PyObject_Str( result );
445  if ( descr && PyBytes_CheckExact( descr ) ) {
446  PyErr_Format( PyExc_TypeError, "can not assign to return object (%s)",
447  PyBytes_AS_STRING( descr ) );
448  } else {
449  PyErr_SetString( PyExc_TypeError, "can not assign to result" );
450  }
451  Py_XDECREF( descr );
452  Py_DECREF( result );
453  Py_DECREF( fAssignable ); fAssignable = 0;
454  return 0;
455  }
456 
457  PyObject* res2 = PyObject_CallFunction( assign, const_cast< char* >( "O" ), fAssignable );
458 
459  Py_DECREF( assign );
460  Py_DECREF( result );
461  Py_DECREF( fAssignable ); fAssignable = 0;
462 
463  if ( res2 ) {
464  Py_DECREF( res2 ); // typically, *this from operator=()
465  Py_INCREF( Py_None );
466  return Py_None;
467  }
468 
469  return 0;
470  }
471 }
472 
473 ////////////////////////////////////////////////////////////////////////////////
474 /// execute <method> with argument <self, ctxt>, construct python ROOT object return ptr value
475 
478 {
479  return BindCppObject( (void*)GILCallR( method, self, ctxt ), fClass, kTRUE );
480 }
481 
482 ////////////////////////////////////////////////////////////////////////////////
483 /// execute <method> with argument <self, ctxt>, construct python ROOT object (ignoring ref) return ptr value
484 
487 {
488  return BindCppObject( *(void**)GILCallR( method, self, ctxt ), fClass, kFALSE );
489 }
490 
491 
492 ////////////////////////////////////////////////////////////////////////////////
493 /// smart pointer excutor
494 
497 {
498  Cppyy::TCppObject_t value = GILCallO( method, self, ctxt, fClass );
499 
500  if ( ! value ) {
501  if ( ! PyErr_Occurred() ) // callee may have set a python error itself
502  PyErr_SetString( PyExc_ValueError, "NULL result where temporary expected" );
503  return 0;
504  }
505 
506 // fixme? - why doesn't this do the same as `self._get_smart_ptr().get()'
508  (void*)GILCallR( (Cppyy::TCppMethod_t)fDereferencer, value, ctxt ), fRawPtrType );
509 
510  if ( pyobj ) {
511  pyobj->SetSmartPtr( (void*)value, fClass );
512  pyobj->HoldOn(); // life-time control by python ref-counting
513  }
514 
515  return (PyObject*)pyobj;
516 }
517 
520 {
521  Cppyy::TCppObject_t value = GILCallR( method, self, ctxt );
522  if ( ! value )
523  return nullptr;
524 
525 // todo: why doesn't this do the same as `self._get_smart_ptr().get()'
527  (void*)GILCallR( (Cppyy::TCppMethod_t)fDereferencer, value, ctxt ), fRawPtrType );
528 
529  if ( pyobj )
530  pyobj->SetSmartPtr( (void*)value, fClass );
531 
532  return (PyObject*)pyobj;
533 }
534 
537 {
538  Cppyy::TCppObject_t value = GILCallR( method, self, ctxt );
539  if ( ! value )
540  return nullptr;
541 
542  //if ( ! fAssignable ) {
543 
544  // fixme? - why doesn't this do the same as `self._get_smart_ptr().get()'
546  (void*)GILCallR( (Cppyy::TCppMethod_t)fDereferencer, value, ctxt ), fRawPtrType );
547 
548  if ( pyobj )
549  pyobj->SetSmartPtr( (void*)value, fClass );
550 
551  return (PyObject*)pyobj;
552 
553  // todo: assignment not done yet
554  //
555  /*} else {
556 
557  PyObject* result = BindCppObject( (void*)value, fClass );
558 
559  // this generic code is quite slow compared to its C++ equivalent ...
560  PyObject* assign = PyObject_GetAttrString( result, const_cast< char* >( "__assign__" ) );
561  if ( ! assign ) {
562  PyErr_Clear();
563  PyObject* descr = PyObject_Str( result );
564  if ( descr && PyBytes_CheckExact( descr ) ) {
565  PyErr_Format( PyExc_TypeError, "can not assign to return object (%s)",
566  PyBytes_AS_STRING( descr ) );
567  } else {
568  PyErr_SetString( PyExc_TypeError, "can not assign to result" );
569  }
570  Py_XDECREF( descr );
571  Py_DECREF( result );
572  Py_DECREF( fAssignable ); fAssignable = 0;
573  return 0;
574  }
575 
576  PyObject* res2 = PyObject_CallFunction( assign, const_cast< char* >( "O" ), fAssignable );
577 
578 
579  Py_DECREF( assign );
580  Py_DECREF( result );
581  Py_DECREF( fAssignable ); fAssignable = 0;
582 
583  if ( res2 ) {
584  Py_DECREF( res2 ); // typically, *this from operator=()
585  Py_INCREF( Py_None );
586  return Py_None;
587  }
588 
589  return 0;
590  }
591  */
592 }
593 
594 
595 ////////////////////////////////////////////////////////////////////////////////
596 /// execute <method> with argument <self, ctxt>, construct TTupleOfInstances from return value
597 
600 {
601  return BindCppObjectArray( (void*)GILCallR( method, self, ctxt ), fClass, fArraySize );
602 }
603 
604 ////////////////////////////////////////////////////////////////////////////////
605 /// package return address in PyObject* for caller to handle appropriately (see
606 /// TConstructorHolder for the actual build of the PyObject)
607 
608 PyObject* PyROOT::TConstructorExecutor::Execute(
610 {
611  return (PyObject*)GILCallConstructor( method, (Cppyy::TCppType_t)klass, ctxt );
612 }
613 
614 ////////////////////////////////////////////////////////////////////////////////
615 /// execute <method> with argument <self, ctxt>, return python object
616 
617 PyObject* PyROOT::TPyObjectExecutor::Execute(
619 {
620  return (PyObject*)GILCallR( method, self, ctxt );
621 }
622 
623 
624 //- factories -----------------------------------------------------------------
625 PyROOT::TExecutor* PyROOT::CreateExecutor( const std::string& fullType,
626  Bool_t manage_smart_ptr )
627 {
628 // The matching of the fulltype to an executor factory goes through up to 4 levels:
629 // 1) full, qualified match
630 // 2) drop '&' as by ref/full type is often pretty much the same python-wise
631 // 3) ROOT classes, either by ref/ptr or by value
632 // 4) additional special case for enums
633 //
634 // If all fails, void is used, which will cause the return type to be ignored on use
635 
636 // an exactly matching executor is best
637  ExecFactories_t::iterator h = gExecFactories.find( fullType );
638  if ( h != gExecFactories.end() )
639  return (h->second)();
640 
641 // resolve typedefs etc., and collect qualifiers
642  std::string resolvedType = Cppyy::ResolveName( fullType );
643 
644 // a full, qualified matching executor is preferred
645  h = gExecFactories.find( resolvedType );
646  if ( h != gExecFactories.end() )
647  return (h->second)();
648 
649 //-- nothing? ok, collect information about the type and possible qualifiers/decorators
650  const std::string& cpd = Utility::Compound( resolvedType );
651  std::string realType = TClassEdit::ShortType( resolvedType.c_str(), 1 );
652 
653 // const-ness (dropped by TClassEdit::ShortType) is in general irrelevant
654  h = gExecFactories.find( realType + cpd );
655  if ( h != gExecFactories.end() )
656  return (h->second)();
657 
658 //-- still nothing? try pointer instead of array (for builtins)
659  if ( cpd == "[]" ) {
660  // CLING WORKAROUND -- if the type is a fixed-size array, it will have a funky
661  // resolved type like MyClass(&)[N], which TClass::GetClass() fails on. So, strip
662  // it down:
663  realType = TClassEdit::CleanType( realType.substr( 0, realType.rfind("(") ).c_str(), 1 );
664  // -- CLING WORKAROUND
665  h = gExecFactories.find( realType + "*" );
666  if ( h != gExecFactories.end() )
667  return (h->second)(); // TODO: use array size
668  }
669 
670 // ROOT classes and special cases (enum)
671  TExecutor* result = 0;
672  if ( Cppyy::TCppType_t klass = Cppyy::GetScope( realType ) ) {
673  if ( manage_smart_ptr && Cppyy::IsSmartPtr( realType ) ) {
674  const std::vector< Cppyy::TCppMethod_t > methods = Cppyy::GetMethodsFromName( klass, "operator->" );
675  if ( ! methods.empty() ) {
676  Cppyy::TCppType_t rawPtrType = Cppyy::GetScope(
677  TClassEdit::ShortType( Cppyy::GetMethodResultType( methods[0] ).c_str(), 1 ) );
678  if ( rawPtrType ) {
679  if ( cpd == "" ) {
680  result = new TCppObjectBySmartPtrExecutor( klass, rawPtrType, methods[0] );
681  } else if ( cpd == "*" ) {
682  result = new TCppObjectBySmartPtrPtrExecutor( klass, rawPtrType, methods[0] );
683  } else if ( cpd == "&" ) {
684  result = new TCppObjectBySmartPtrRefExecutor( klass, rawPtrType, methods[0] );
685  } /* else if ( cpd == "**" ) {
686  } else if ( cpd == "*&" || cpd == "&*" ) {
687  } else if ( cpd == "[]" ) {
688  } else {
689  } */
690  }
691  }
692  }
693 
694  if ( ! result ) {
695  if ( cpd == "" )
696  result = new TCppObjectByValueExecutor( klass );
697  else if ( cpd == "&" )
698  result = new TCppObjectRefExecutor( klass );
699  else if ( cpd == "**" )
700  result = new TCppObjectPtrPtrExecutor( klass );
701  else if ( cpd == "*&" || cpd == "&*" )
702  result = new TCppObjectPtrRefExecutor( klass );
703  else if ( cpd == "[]" ) {
704  Py_ssize_t asize = Utility::ArraySize( resolvedType );
705  if ( 0 < asize )
706  result = new TCppObjectArrayExecutor( klass, asize );
707  else
708  result = new TCppObjectPtrRefExecutor( klass );
709  } else
710  result = new TCppObjectExecutor( klass );
711  }
712  } else if ( Cppyy::IsEnum( realType ) ) {
713  // enums don't resolve to unsigned ints, but that's what they are ...
714  h = gExecFactories.find( "UInt_t" + cpd );
715  } else {
716  // handle (with warning) unknown types
717  std::stringstream s;
718  s << "creating executor for unknown type \"" << fullType << "\"" << std::ends;
719  PyErr_Warn( PyExc_RuntimeWarning, (char*)s.str().c_str() );
720  // void* may work ("user knows best"), void will fail on use of return value
721  h = (cpd == "") ? gExecFactories.find( "void" ) : gExecFactories.find( "void*" );
722  }
723 
724  if ( ! result && h != gExecFactories.end() )
725  // executor factory available, use it to create executor
726  result = (h->second)();
727 
728  return result; // may still be null
729 }
730 
731 ////////////////////////////////////////////////////////////////////////////////
732 
733 #define PYROOT_EXECUTOR_FACTORY( name ) \
734 TExecutor* Create##name##Executor() \
735 { \
736  return new T##name##Executor; \
737 }
738 
739 namespace {
740 
741  using namespace PyROOT;
742 
743 // use macro rather than template for portability ...
745  PYROOT_EXECUTOR_FACTORY( BoolRef )
746  PYROOT_EXECUTOR_FACTORY( BoolConstRef )
748  PYROOT_EXECUTOR_FACTORY( CharRef )
749  PYROOT_EXECUTOR_FACTORY( CharConstRef )
751  PYROOT_EXECUTOR_FACTORY( UCharRef )
752  PYROOT_EXECUTOR_FACTORY( UCharConstRef )
753  PYROOT_EXECUTOR_FACTORY( ShortRef )
754  PYROOT_EXECUTOR_FACTORY( UShortRef )
756  PYROOT_EXECUTOR_FACTORY( IntRef )
757  PYROOT_EXECUTOR_FACTORY( UIntRef )
759  PYROOT_EXECUTOR_FACTORY( ULongRef )
761  PYROOT_EXECUTOR_FACTORY( LongRef )
763  PYROOT_EXECUTOR_FACTORY( FloatRef )
765  PYROOT_EXECUTOR_FACTORY( DoubleRef )
766  PYROOT_EXECUTOR_FACTORY( LongDouble )
767  PYROOT_EXECUTOR_FACTORY( LongDoubleRef )
769  PYROOT_EXECUTOR_FACTORY( LongLong )
770  PYROOT_EXECUTOR_FACTORY( LongLongRef )
771  PYROOT_EXECUTOR_FACTORY( ULongLong )
772  PYROOT_EXECUTOR_FACTORY( ULongLongRef )
773  PYROOT_EXECUTOR_FACTORY( CString )
774  PYROOT_EXECUTOR_FACTORY( VoidArray )
775  PYROOT_EXECUTOR_FACTORY( BoolArray )
776  PYROOT_EXECUTOR_FACTORY( ShortArray )
777  PYROOT_EXECUTOR_FACTORY( UShortArray )
778  PYROOT_EXECUTOR_FACTORY( IntArray )
779  PYROOT_EXECUTOR_FACTORY( UIntArray )
780  PYROOT_EXECUTOR_FACTORY( LongArray )
781  PYROOT_EXECUTOR_FACTORY( ULongArray )
782  PYROOT_EXECUTOR_FACTORY( FloatArray )
783  PYROOT_EXECUTOR_FACTORY( DoubleArray )
784  PYROOT_EXECUTOR_FACTORY( STLString )
785  PYROOT_EXECUTOR_FACTORY( STLStringRef )
787  PYROOT_EXECUTOR_FACTORY( Constructor )
789 
790 // executor factories for ROOT types
791  typedef std::pair< const char*, ExecutorFactory_t > NFp_t;
792 
793  NFp_t factories_[] = {
794  // factories for built-ins
795  NFp_t( "bool", &CreateBoolExecutor ),
796  NFp_t( "bool&", &CreateBoolRefExecutor ),
797  NFp_t( "const bool&", &CreateBoolConstRefExecutor ),
798  NFp_t( "char", &CreateCharExecutor ),
799  NFp_t( "signed char", &CreateCharExecutor ),
800  NFp_t( "unsigned char", &CreateUCharExecutor ),
801  NFp_t( "char&", &CreateCharRefExecutor ),
802  NFp_t( "signed char&", &CreateCharRefExecutor ),
803  NFp_t( "unsigned char&", &CreateUCharRefExecutor ),
804  NFp_t( "const char&", &CreateCharConstRefExecutor ),
805  NFp_t( "const signed char&", &CreateCharConstRefExecutor ),
806  NFp_t( "const unsigned char&", &CreateUCharConstRefExecutor ),
807  NFp_t( "short", &CreateIntExecutor ),
808  NFp_t( "short&", &CreateShortRefExecutor ),
809  NFp_t( "unsigned short", &CreateIntExecutor ),
810  NFp_t( "unsigned short&", &CreateUShortRefExecutor ),
811  NFp_t( "int", &CreateIntExecutor ),
812  NFp_t( "int&", &CreateIntRefExecutor ),
813  NFp_t( "unsigned int", &CreateULongExecutor ),
814  NFp_t( "unsigned int&", &CreateUIntRefExecutor ),
815  NFp_t( "UInt_t", /* enum */ &CreateULongExecutor ),
816  NFp_t( "UInt_t&", /* enum */ &CreateUIntRefExecutor ),
817  NFp_t( "long", &CreateLongExecutor ),
818  NFp_t( "long&", &CreateLongRefExecutor ),
819  NFp_t( "unsigned long", &CreateULongExecutor ),
820  NFp_t( "unsigned long&", &CreateULongRefExecutor ),
821  NFp_t( "long long", &CreateLongLongExecutor ),
822  NFp_t( "Long64_t", &CreateLongLongExecutor ),
823  NFp_t( "long long&", &CreateLongLongRefExecutor ),
824  NFp_t( "Long64_t&", &CreateLongLongRefExecutor ),
825  NFp_t( "unsigned long long", &CreateULongLongExecutor ),
826  NFp_t( "ULong64_t", &CreateULongLongExecutor ),
827  NFp_t( "unsigned long long&", &CreateULongLongRefExecutor ),
828  NFp_t( "ULong64_t&", &CreateULongLongRefExecutor ),
829 
830  NFp_t( "float", &CreateFloatExecutor ),
831  NFp_t( "float&", &CreateFloatRefExecutor ),
832  NFp_t( "double", &CreateDoubleExecutor ),
833  NFp_t( "double&", &CreateDoubleRefExecutor ),
834  NFp_t( "long double", &CreateLongDoubleExecutor ), // TODO: lost precision
835  NFp_t( "long double&", &CreateLongDoubleRefExecutor ),
836  NFp_t( "void", &CreateVoidExecutor ),
837 
838  // pointer/array factories
839  NFp_t( "void*", &CreateVoidArrayExecutor ),
840  NFp_t( "bool*", &CreateBoolArrayExecutor ),
841  NFp_t( "short*", &CreateShortArrayExecutor ),
842  NFp_t( "unsigned short*", &CreateUShortArrayExecutor ),
843  NFp_t( "int*", &CreateIntArrayExecutor ),
844  NFp_t( "unsigned int*", &CreateUIntArrayExecutor ),
845  NFp_t( "long*", &CreateLongArrayExecutor ),
846  NFp_t( "unsigned long*", &CreateULongArrayExecutor ),
847  NFp_t( "float*", &CreateFloatArrayExecutor ),
848  NFp_t( "double*", &CreateDoubleArrayExecutor ),
849 
850  // factories for special cases
851  NFp_t( "const char*", &CreateCStringExecutor ),
852  NFp_t( "char*", &CreateCStringExecutor ),
853  NFp_t( "std::string", &CreateSTLStringExecutor ),
854  NFp_t( "string", &CreateSTLStringExecutor ),
855  NFp_t( "std::string&", &CreateSTLStringRefExecutor ),
856  NFp_t( "string&", &CreateSTLStringRefExecutor ),
857  NFp_t( "TGlobal*", &CreateTGlobalExecutor ),
858  NFp_t( "__init__", &CreateConstructorExecutor ),
859  NFp_t( "PyObject*", &CreatePyObjectExecutor ),
860  NFp_t( "_object*", &CreatePyObjectExecutor ),
861  NFp_t( "FILE*", &CreateVoidArrayExecutor )
862  };
863 
864  struct InitExecFactories_t {
865  public:
866  InitExecFactories_t()
867  {
868  // load all executor factories in the global map 'gExecFactories'
869  int nf = sizeof( factories_ ) / sizeof( factories_[ 0 ] );
870  for ( int i = 0; i < nf; ++i ) {
871  gExecFactories[ factories_[ i ].first ] = factories_[ i ].second;
872  }
873  }
874  } initExecvFactories_;
875 
876 } // unnamed namespace
virtual PyObject * Execute(Cppyy::TCppMethod_t, Cppyy::TCppObject_t, TCallContext *)
Definition: Executors.cxx:535
#define PyBytes_CheckExact
Definition: PyROOT.h:53
PyObject * fAssignable
Definition: Executors.h:89
TCppScope_t TCppType_t
Definition: Cppyy.h:13
static PyObject * PyROOT_PyBool_FromInt(Int_t b)
Definition: Executors.cxx:93
static double B[]
#define PyROOT_PyUnicode_FromString
Definition: PyROOT.h:71
virtual PyObject * Execute(Cppyy::TCppMethod_t, Cppyy::TCppObject_t, TCallContext *)
execute <method> with argument <self, ctxt>, construct python ROOT object (ignoring ref) return ptr v...
Definition: Executors.cxx:485
long long Long64_t
Definition: RtypesCore.h:69
#define PyROOT_PyUnicode_GET_SIZE
Definition: PyROOT.h:68
float Float_t
Definition: RtypesCore.h:53
#define PYROOT_EXECUTOR_FACTORY(name)
Definition: Executors.cxx:733
return c
const char * Int
RooArgList L(const RooAbsArg &v1)
TExecutor * CreateExecutor(const std::string &fullType, Bool_t manage_smart_ptr=kTRUE)
Definition: Executors.cxx:625
unsigned short UShort_t
Definition: RtypesCore.h:36
TH1 * h
Definition: legend2.C:5
std::vector< TCppMethod_t > GetMethodsFromName(TCppScope_t scope, const std::string &name)
Definition: Cppyy.cxx:663
std::string CleanType(const char *typeDesc, int mode=0, const char **tail=0)
Cleanup type description, redundant blanks removed and redundant tail ignored return *tail = pointer ...
const char * Long
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
#define PYROOT_IMPLEMENT_ARRAY_EXECUTOR(name, type)
Definition: Executors.cxx:349
ExecFactories_t gExecFactories
Definition: Executors.cxx:27
const Bool_t kFALSE
Definition: Rtypes.h:92
const char * Char
const char * UShort
PyObject * BindCppObjectArray(Cppyy::TCppObject_t address, Cppyy::TCppType_t klass, Int_t size)
TODO: this function exists for symmetry; need to figure out if it's useful.
const char * UInt
virtual PyObject * Execute(Cppyy::TCppMethod_t, Cppyy::TCppObject_t, TCallContext *)
execute <method> with argument <self, ctxt>, construct python ROOT object return ptr value ...
Definition: Executors.cxx:476
TCppObject_t CallO(TCppMethod_t method, TCppObject_t self, void *args, TCppType_t result_type)
Definition: Cppyy.cxx:472
std::vector< TParameter > fArgs
Definition: TCallContext.h:57
TCppObject_t CallConstructor(TCppMethod_t method, TCppType_t type, void *args)
Definition: Cppyy.cxx:458
Bool_t ReleasesGIL(UInt_t flags)
Definition: TCallContext.h:77
ULong64_t
Definition: Executors.cxx:279
#define PyROOT_PyUnicode_FromFormat
Definition: PyROOT.h:70
std::string ResolveName(const std::string &cppitem_name)
Definition: Cppyy.cxx:140
static Cppyy::TCppObject_t GILCallConstructor(Cppyy::TCppMethod_t method, Cppyy::TCppType_t klass, PyROOT::TCallContext *ctxt)
Definition: Executors.cxx:82
PyLong_FromUnsignedLongLong
Definition: Executors.cxx:279
void SetSmartPtr(void *address, Cppyy::TCppType_t ptrType)
Definition: ObjectProxy.h:40
TClass * fClass
pointer to the foreign object
virtual PyObject * Execute(Cppyy::TCppMethod_t, Cppyy::TCppObject_t, TCallContext *)
execute <method> with argument <self, ctxt>, construct TTupleOfInstances from return value ...
Definition: Executors.cxx:598
#define PyROOT_PyUnicode_AsString
Definition: PyROOT.h:66
const char * UChar
const char * Float
R__EXTERN PyObject * gNullPtrObject
Definition: Converters.cxx:35
ULong_t PyLongOrInt_AsULong(PyObject *pyobject)
Definition: Utility.cxx:145
virtual PyObject * Execute(Cppyy::TCppMethod_t, Cppyy::TCppObject_t, TCallContext *)
smart pointer excutor
Definition: Executors.cxx:495
#define F(x, y, z)
ptrdiff_t TCppMethod_t
Definition: Cppyy.h:15
static double C[]
#define PYROOT_IMPL_GILCALL(rtype, tcode)
Definition: Executors.cxx:56
virtual PyObject * Execute(Cppyy::TCppMethod_t, Cppyy::TCppObject_t, TCallContext *)
execute <method> with argument <self, ctxt>, construct python proxy object return value ...
Definition: Executors.cxx:399
virtual PyObject * Execute(Cppyy::TCppMethod_t, Cppyy::TCppObject_t, TCallContext *)
execution will bring a temporary in existence
Definition: Executors.cxx:408
#define PyROOT_PyUnicode_FromStringAndSize
Definition: PyROOT.h:75
unsigned int UInt_t
Definition: RtypesCore.h:42
PyObject * BindCppGlobal(TGlobal *)
gbl == 0 means global does not exist (rather than gbl is NULL pointer)
virtual PyObject * Execute(Cppyy::TCppMethod_t, Cppyy::TCppObject_t, TCallContext *)
smart pointer excutor
Definition: Executors.cxx:518
const char * ULong
ULong64_t PyLongOrInt_AsULong64(PyObject *pyobject)
Convert <pyobject> to C++ unsigned long long, with bounds checking.
Definition: Utility.cxx:166
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)
short Short_t
Definition: RtypesCore.h:35
const char * Double
virtual Bool_t SetAssignable(PyObject *)
prepare "buffer" for by-ref returns, used with setitem
Definition: Executors.cxx:237
long double LongDouble_t
Definition: RtypesCore.h:57
Global variables class (global variables are obtained from CINT).
Definition: TGlobal.h:29
void * TCppObject_t
Definition: Cppyy.h:14
static Cppyy::TCppObject_t GILCallO(Cppyy::TCppMethod_t method, Cppyy::TCppObject_t self, PyROOT::TCallContext *ctxt, Cppyy::TCppType_t klass)
Definition: Executors.cxx:76
PyObject * PyBuffer_FromMemory(Bool_t *buf, Py_ssize_t size=-1)
long Long_t
Definition: RtypesCore.h:50
#define PYROOT_IMPLEMENT_BASIC_REFEXECUTOR(name, type, stype, F1, F2)
Definition: Executors.cxx:251
TCppScope_t GetScope(const std::string &scope_name)
Definition: Cppyy.cxx:150
double Double_t
Definition: RtypesCore.h:55
std::string GetMethodResultType(TCppMethod_t)
Definition: Cppyy.cxx:717
static const float S
Definition: mandel.cpp:113
unsigned long long ULong64_t
Definition: RtypesCore.h:70
unsigned long ULong_t
Definition: RtypesCore.h:51
Bool_t IsSmartPtr(const std::string &)
Definition: Cppyy.cxx:584
const char * Bool
#define R__EXTERN
Definition: DllImport.h:27
char Char_t
Definition: RtypesCore.h:29
int Py_ssize_t
Definition: PyROOT.h:154
static TPyBufferFactory * Instance()
virtual PyObject * Execute(Cppyy::TCppMethod_t, Cppyy::TCppObject_t, TCallContext *)
executor binds the result to the left-hand side, overwriting if an old object
Definition: Executors.cxx:433
std::string ShortType(const char *typeDesc, int mode)
Return the absolute type of typeDesc.
std::map< std::string, ExecutorFactory_t > ExecFactories_t
Definition: Executors.cxx:26
double result[121]
Py_ssize_t ArraySize(const std::string &name)
Extract size from an array type, if available.
Definition: Utility.cxx:674
unsigned char UChar_t
Definition: RtypesCore.h:34
#define I(x, y, z)
const Bool_t kTRUE
Definition: Rtypes.h:91
#define PyBytes_AS_STRING
Definition: PyROOT.h:54
float value
Definition: math.cpp:443
ptrdiff_t TCppScope_t
Definition: Cppyy.h:12
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)
Bool_t IsEnum(const std::string &type_name)
Definition: Cppyy.cxx:528
TRandom3 R
a TMatrixD.
Definition: testIO.cxx:28
_object PyObject
Definition: TPyArg.h:22
R__EXTERN PyObject * gEmptyString
Definition: PyStrings.h:23
static PyObject * PyROOT_PyUnicode_FromInt(Int_t c)
Definition: Executors.cxx:88
const std::string Compound(const std::string &name)
Break down the compound of a fully qualified type name.
Definition: Utility.cxx:650
const char * Short