41 if ( fRelease ) fSave = PyEval_SaveThread();
46 if ( fRelease ) PyEval_RestoreThread( fSave );
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 ); \
78 GILControl gc( ctxt );
79 return Cppyy::CallO( method,
self, &ctxt->fArgs, klass );
84 GILControl gc( ctxt );
89 if ( c < 0 )
return PyInt_FromLong( c );
101 PyObject* PyROOT::TBoolExecutor::Execute(
105 Bool_t retval = GILCallB( method,
self, ctxt );
106 PyObject* result = retval ? Py_True : Py_False;
114 PyObject* PyROOT::TBoolConstRefExecutor::Execute(
124 PyObject* PyROOT::TCharExecutor::Execute(
134 PyObject* PyROOT::TCharConstRefExecutor::Execute(
144 PyObject* PyROOT::TUCharExecutor::Execute(
154 PyObject* PyROOT::TUCharConstRefExecutor::Execute(
163 PyObject* PyROOT::TIntExecutor::Execute(
166 return PyInt_FromLong( (
Int_t)GILCallI( method,
self, ctxt ) );
172 PyObject* PyROOT::TLongExecutor::Execute(
175 return PyLong_FromLong( (
Long_t)GILCallL( method,
self, ctxt ) );
181 PyObject* PyROOT::TULongExecutor::Execute(
184 return PyLong_FromUnsignedLong( (
ULong_t)GILCallLL( method,
self, ctxt ) );
190 PyObject* PyROOT::TLongLongExecutor::Execute(
193 Long64_t result = GILCallLL( method,
self, ctxt );
194 return PyLong_FromLongLong( result );
200 PyObject* PyROOT::TULongLongExecutor::Execute(
210 PyObject* PyROOT::TFloatExecutor::Execute(
213 return PyFloat_FromDouble( (
Double_t)GILCallF( method,
self, ctxt ) );
219 PyObject* PyROOT::TDoubleExecutor::Execute(
222 return PyFloat_FromDouble( (
Double_t)GILCallD( method,
self, ctxt ) );
228 PyObject* PyROOT::TLongDoubleExecutor::Execute(
231 return PyFloat_FromDouble( (
Double_t)GILCallLD( method,
self, ctxt ) );
239 if ( pyobject != 0 ) {
240 Py_INCREF( pyobject );
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 )\
255 type* ref = (type*)GILCallR( method, self, ctxt ); \
256 if ( ! fAssignable ) \
257 return F1( (stype)*ref ); \
259 *ref = (type)F2( fAssignable ); \
260 Py_DECREF( fAssignable ); \
262 Py_INCREF( Py_None ); \
277 LongLong,
Long64_t, Long64_t, PyLong_FromLongLong, PyLong_AsLongLong )
283 LongDouble,
LongDouble_t, LongDouble_t, PyFloat_FromDouble, PyFloat_AsDouble )
288 PyObject* PyROOT::TSTLStringRefExecutor::Execute(
291 if ( ! fAssignable ) {
292 std::string* result = (std::string*)GILCallR( method,
self, ctxt );
295 std::string* result = (std::string*)GILCallR( method,
self, ctxt );
296 *result = std::string(
299 Py_DECREF( fAssignable );
302 Py_INCREF( Py_None );
310 PyObject* PyROOT::TVoidExecutor::Execute(
313 GILCallV( method,
self, ctxt );
314 Py_INCREF( Py_None );
321 PyObject* PyROOT::TCStringExecutor::Execute(
324 char* result = (
char*)GILCallS( method,
self, ctxt );
335 PyObject* PyROOT::TVoidArrayExecutor::Execute(
339 Long_t* result = (
Long_t*)GILCallR( method,
self, ctxt );
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 )\
353 return BufFac_t::Instance()->PyBuffer_FromMemory( (type*)GILCallR( method, self, ctxt ) );\
368 PyObject* PyROOT::TSTLStringExecutor::Execute(
374 std::string* result = (std::string*)
GILCallO( method,
self, ctxt, sSTLStringScope );
390 PyObject* PyROOT::TTGlobalExecutor::Execute(
414 if ( ! PyErr_Occurred() )
415 PyErr_SetString( PyExc_ValueError,
"NULL result where temporary expected" );
437 if ( ! result || ! fAssignable )
441 PyObject* assign = PyObject_GetAttrString( result, const_cast< char* >(
"__assign__" ) );
444 PyObject* descr = PyObject_Str( result );
446 PyErr_Format( PyExc_TypeError,
"can not assign to return object (%s)",
449 PyErr_SetString( PyExc_TypeError,
"can not assign to result" );
453 Py_DECREF( fAssignable ); fAssignable = 0;
457 PyObject* res2 = PyObject_CallFunction( assign, const_cast< char* >(
"O" ), fAssignable );
461 Py_DECREF( fAssignable ); fAssignable = 0;
465 Py_INCREF( Py_None );
501 if ( ! PyErr_Occurred() )
502 PyErr_SetString( PyExc_ValueError,
"NULL result where temporary expected" );
608 PyObject* PyROOT::TConstructorExecutor::Execute(
617 PyObject* PyROOT::TPyObjectExecutor::Execute(
620 return (
PyObject*)GILCallR( method,
self, ctxt );
639 return (h->second)();
647 return (h->second)();
656 return (h->second)();
667 return (h->second)();
675 if ( ! methods.empty() ) {
681 }
else if ( cpd ==
"*" ) {
683 }
else if ( cpd ==
"&" ) {
697 else if ( cpd ==
"&" )
699 else if ( cpd ==
"**" )
701 else if ( cpd ==
"*&" || cpd ==
"&*" )
703 else if ( cpd ==
"[]" ) {
718 s <<
"creating executor for unknown type \"" << fullType <<
"\"" << std::ends;
719 PyErr_Warn( PyExc_RuntimeWarning, (
char*)s.str().c_str() );
726 result = (h->second)();
733 #define PYROOT_EXECUTOR_FACTORY( name ) \
734 TExecutor* Create##name##Executor() \
736 return new T##name##Executor; \
741 using namespace PyROOT;
791 typedef std::pair< const char*, ExecutorFactory_t > NFp_t;
793 NFp_t factories_[] = {
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", &CreateULongExecutor ),
816 NFp_t(
"UInt_t&", &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 ),
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 ),
835 NFp_t(
"long double&", &CreateLongDoubleRefExecutor ),
836 NFp_t(
"void", &CreateVoidExecutor ),
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 ),
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 )
864 struct InitExecFactories_t {
866 InitExecFactories_t()
869 int nf =
sizeof( factories_ ) /
sizeof( factories_[ 0 ] );
870 for (
int i = 0; i < nf; ++i ) {
874 } initExecvFactories_;
virtual PyObject * Execute(Cppyy::TCppMethod_t, Cppyy::TCppObject_t, TCallContext *)
#define PyBytes_CheckExact
static PyObject * PyROOT_PyBool_FromInt(Int_t b)
#define PyROOT_PyUnicode_FromString
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...
#define PyROOT_PyUnicode_GET_SIZE
#define PYROOT_EXECUTOR_FACTORY(name)
RooArgList L(const RooAbsArg &v1)
TExecutor * CreateExecutor(const std::string &fullType, Bool_t manage_smart_ptr=kTRUE)
std::vector< TCppMethod_t > GetMethodsFromName(TCppScope_t scope, const std::string &name)
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 ...
#define PYROOT_IMPLEMENT_ARRAY_EXECUTOR(name, type)
ExecFactories_t gExecFactories
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.
virtual PyObject * Execute(Cppyy::TCppMethod_t, Cppyy::TCppObject_t, TCallContext *)
execute <method> with argument <self, ctxt>, construct python ROOT object return ptr value ...
TCppObject_t CallO(TCppMethod_t method, TCppObject_t self, void *args, TCppType_t result_type)
std::vector< TParameter > fArgs
TCppObject_t CallConstructor(TCppMethod_t method, TCppType_t type, void *args)
Bool_t ReleasesGIL(UInt_t flags)
#define PyROOT_PyUnicode_FromFormat
std::string ResolveName(const std::string &cppitem_name)
static Cppyy::TCppObject_t GILCallConstructor(Cppyy::TCppMethod_t method, Cppyy::TCppType_t klass, PyROOT::TCallContext *ctxt)
PyLong_FromUnsignedLongLong
void SetSmartPtr(void *address, Cppyy::TCppType_t ptrType)
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 ...
#define PyROOT_PyUnicode_AsString
R__EXTERN PyObject * gNullPtrObject
ULong_t PyLongOrInt_AsULong(PyObject *pyobject)
virtual PyObject * Execute(Cppyy::TCppMethod_t, Cppyy::TCppObject_t, TCallContext *)
smart pointer excutor
#define PYROOT_IMPL_GILCALL(rtype, tcode)
virtual PyObject * Execute(Cppyy::TCppMethod_t, Cppyy::TCppObject_t, TCallContext *)
execute <method> with argument <self, ctxt>, construct python proxy object return value ...
virtual PyObject * Execute(Cppyy::TCppMethod_t, Cppyy::TCppObject_t, TCallContext *)
execution will bring a temporary in existence
#define PyROOT_PyUnicode_FromStringAndSize
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
ULong64_t PyLongOrInt_AsULong64(PyObject *pyobject)
Convert <pyobject> to C++ unsigned long long, with bounds checking.
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)
virtual Bool_t SetAssignable(PyObject *)
prepare "buffer" for by-ref returns, used with setitem
Global variables class (global variables are obtained from CINT).
static Cppyy::TCppObject_t GILCallO(Cppyy::TCppMethod_t method, Cppyy::TCppObject_t self, PyROOT::TCallContext *ctxt, Cppyy::TCppType_t klass)
PyObject * PyBuffer_FromMemory(Bool_t *buf, Py_ssize_t size=-1)
#define PYROOT_IMPLEMENT_BASIC_REFEXECUTOR(name, type, stype, F1, F2)
TCppScope_t GetScope(const std::string &scope_name)
std::string GetMethodResultType(TCppMethod_t)
unsigned long long ULong64_t
Bool_t IsSmartPtr(const std::string &)
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
std::string ShortType(const char *typeDesc, int mode)
Return the absolute type of typeDesc.
std::map< std::string, ExecutorFactory_t > ExecFactories_t
Py_ssize_t ArraySize(const std::string &name)
Extract size from an array type, if available.
#define PyBytes_AS_STRING
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)
R__EXTERN PyObject * gEmptyString
static PyObject * PyROOT_PyUnicode_FromInt(Int_t c)
const std::string Compound(const std::string &name)
Break down the compound of a fully qualified type name.