55 for (
int i = 0; i < (int)fConverters.size(); ++i )
56 delete fConverters[ i ];
71 }
catch ( std::exception& e ) {
76 std::string exception_type;
77 if (cl) exception_type = cl->
GetName();
81 if (errorCode) exception_type =
typeid(e).
name();
82 else exception_type = demangled.get();
84 PyObject* pyexc = PyDict_GetItemString( pyUserExcepts, exception_type.c_str() );
87 pyexc = PyDict_GetItemString( pyUserExcepts, (
"std::"+exception_type).c_str() );
91 pyexc = PyDict_GetItemString( pyUserExcepts, (
"ROOT::"+exception_type).c_str() );
93 Py_DECREF( pyUserExcepts );
96 PyErr_Format( pyexc,
"%s", e.what() );
98 PyErr_Format( PyExc_Exception,
"%s (C++ exception of type %s)", e.what(), exception_type.c_str() );
102 PyErr_SetString( PyExc_Exception,
"unhandled, unknown C++ exception" );
117 result = CallFast(
self, offset, ctxt );
119 PyErr_SetString( PyExc_SystemError,
"problem in C++; program state has been reset" );
133 fConverters.resize( nArgs );
136 for (
size_t iarg = 0; iarg < nArgs; ++iarg ) {
146 ( fullType ==
"const std::string&" || fullType ==
"const std::string &"
147 || fullType ==
"const string&" || fullType ==
"const string &" ) ) {
153 if ( ! fConverters[ iarg ] ) {
154 PyErr_Format( PyExc_TypeError,
"argument type %s not handled", fullType.c_str() );
183 std::stringstream sig; sig <<
"(";
186 for (
size_t iarg = 0; iarg < nArgs; ++iarg ) {
187 if ( ifirst ) sig <<
", ";
192 if ( ! parname.empty() )
193 sig <<
" " << parname;
196 if ( ! defvalue.empty() )
197 sig <<
" = " << defvalue;
210 PyErr_Fetch( &etype, &evalue, &etrace );
212 std::string details =
"";
214 PyObject* descr = PyObject_Str( evalue );
221 Py_XDECREF( evalue ); Py_XDECREF( etrace );
224 PyObject* errtype = etype ? etype : PyExc_TypeError;
225 if ( details.empty() ) {
229 PyErr_Format( errtype,
"%s =>\n %s (%s)",
232 PyErr_Format( errtype,
"%s =>\n %s",
244 fMethod( method ), fScope( scope ), fExecutor(
nullptr ), fArgsRequired( -1 ),
251 PyCallable( other ), fMethod( other.fMethod ), fScope( other.fScope )
262 if (
this != &other ) {
289 GetSignatureString().c_str() );
302 for (
size_t iarg = 0; iarg < nArgs; ++iarg ) {
310 if ( strstr( aname.c_str(),
"void*" ) )
313 else if ( strstr( aname.c_str(),
"float" ) )
315 else if ( strstr( aname.c_str(),
"long double" ) )
317 else if ( strstr( aname.c_str(),
"double" ) )
320 else if ( strstr( aname.c_str(),
"bool" ) )
325 if ( aname[ aname.size() - 1 ] ==
'&' )
333 if ( aname ==
"IBaseFunctionMultiDim")
335 else if ( aname ==
"RooAbsReal" )
366 int co_argcount = (int)GetMaxArgs() ;
370 PyObject* co_varnames = PyTuple_New( co_argcount + 1 );
372 for (
int iarg = 0; iarg < co_argcount; ++iarg ) {
375 if ( ! parname.empty() ) {
382 PyTuple_SET_ITEM( co_varnames, iarg + 1, pyspec );
393 if ( iarg >= (
int)GetMaxArgs() )
397 if ( ! defvalue.empty() ) {
402 if ( ! pyval && PyErr_Occurred() ) {
426 if ( fIsInitialized ==
kTRUE )
429 if ( ! InitConverters_() )
432 if ( ! InitExecutor_( fExecutor, ctxt ) )
439 fIsInitialized =
kTRUE;
455 if ( PyTuple_GET_SIZE( args ) != 0 ) {
469 return PyTuple_GetSlice( args, 1, PyTuple_GET_SIZE( args ) );
475 "unbound method %s::%s must be called with a %s instance as first argument",
485 int argc = PyTuple_GET_SIZE( args );
486 int argMax = fConverters.size();
489 if ( argc < fArgsRequired ) {
491 "takes at least %d arguments (%d given)", fArgsRequired, argc ) );
493 }
else if ( argMax < argc ) {
495 "takes at most %d arguments (%d given)", argMax, argc ) );
500 ctxt->
fArgs.resize( argc );
501 for (
int i = 0; i < argc; ++i ) {
502 if ( ! fConverters[ i ]->SetArg(
503 PyTuple_GET_ITEM( args, i ), ctxt->
fArgs[i], ctxt ) ) {
521 result = CallFast(
self, offset, ctxt );
524 result = CallSafe(
self, offset, ctxt );
534 }
else if ( ! result && PyErr_Occurred() )
546 if ( kwds != 0 && PyDict_Size( kwds ) ) {
547 PyErr_SetString( PyExc_TypeError,
"keyword arguments are not yet supported" );
556 if ( ! ( args = PreProcessArgs(
self, args, kwds ) ) )
560 Bool_t bConvertOk = ConvertAndSetArgs( args, ctxt );
563 if ( bConvertOk ==
kFALSE )
567 void*
object =
self->GetObject();
571 PyErr_SetString( PyExc_ReferenceError,
"attempt to access a null-pointer" );
580 if ( derived && derived != fScope )
591 derived && pyobj->
ObjectIsA() == derived &&
#define PyROOT_PyUnicode_FromString
Cppyy::TCppScope_t fScope
std::string GetScopedFinalName(TCppType_t type)
virtual Int_t GetPriority()
Method priorities exist (in lieu of true overloading) there to prevent void* or <unknown>* from usurp...
TMethodHolder & operator=(const TMethodHolder &)
assignment operator
Bool_t IsBuiltin(const std::string &type_name)
TExecutor * CreateExecutor(const std::string &fullType, Bool_t manage_smart_ptr=kTRUE)
static ECallFlags sSignalPolicy
virtual PyObject * GetArgDefault(Int_t iarg)
get the default value (if any) of argument iarg of this method
ptrdiff_t GetBaseOffset(TCppType_t derived, TCppType_t base, TCppObject_t address, int direction, bool rerror=false)
TCppIndex_t GetMethodReqArgs(TCppMethod_t)
std::string GetFinalName(TCppType_t type)
virtual PyObject * GetPrototype()
Bool_t ManagesSmartPtr(TCallContext *ctxt)
virtual Bool_t Initialize(TCallContext *ctxt=0)
done if cache is already setup
virtual PyObject * Call(ObjectProxy *&self, PyObject *args, PyObject *kwds, TCallContext *ctxt=0)
preliminary check in case keywords are accidently used (they are ignored otherwise) ...
std::vector< TParameter > fArgs
virtual PyObject * GetScopeProxy()
Get or build the scope of this method.
void Destroy_() const
destroy executor and argument converters
#define PyROOT_PyUnicode_FromFormat
R__EXTERN void * TPyExceptionMagic
std::string ResolveName(const std::string &cppitem_name)
R__EXTERN PyObject * gRootModule
std::string GetReturnTypeName()
PyObject * CallSafe(void *, ptrdiff_t, TCallContext *)
Helper code to prevent some code duplication; this code embeds a ROOT "try/catch" block that saves th...
char * DemangleTypeIdName(const std::type_info &ti, int &errorCode)
Demangle in a portable way the type id name.
#define PyROOT_PyUnicode_AsString
PyObject * PyErr_Occurred_WithGIL()
Re-acquire the GIL before calling PyErr_Occurred() in case it has been released; note that the p2...
virtual Bool_t InitExecutor_(TExecutor *&, TCallContext *ctxt=0)
install executor conform to the return type
Bool_t IsComplete(const std::string &type_name)
void SetPyError_(PyObject *msg)
helper to report errors in a consistent format (derefs msg)
Cppyy::TCppType_t ObjectIsA() const
virtual PyObject * GetSignature()
TConverter * CreateConverter(const std::string &fullType, Long_t size=-1)
void Copy_(const TMethodHolder &)
virtual PyObject * Execute(void *self, ptrdiff_t offset, TCallContext *ctxt=0)
call the interface method
Bool_t ObjectProxy_Check(T *object)
std::string GetMethodName(TCppMethod_t)
void Initialize(Bool_t useTMVAStyle=kTRUE)
virtual const char * GetName() const
Returns name of object.
The ROOT global object gROOT contains a list of all defined classes.
std::string GetSignatureString()
built a signature representation (used for doc strings)
virtual PyObject * PreProcessArgs(ObjectProxy *&self, PyObject *args, PyObject *kwds)
verify existence of self, return if ok
Bool_t IsSubtype(TCppType_t derived, TCppType_t base)
virtual PyObject * GetCoVarNames()
Build a tuple of the argument types/names.
PyObject * CreateScopeProxy(Cppyy::TCppScope_t)
Convenience function with a lookup first through the known existing proxies.
TMethodHolder(Cppyy::TCppScope_t scope, Cppyy::TCppMethod_t method)
TCppScope_t GetScope(const std::string &scope_name)
std::string GetMethodResultType(TCppMethod_t)
PyObject * CallFast(void *, ptrdiff_t, TCallContext *)
Helper code to prevent some duplication; this is called from CallSafe() as well as directly from TMet...
TCppIndex_t GetMethodNumArgs(TCppMethod_t)
std::string GetMethodArgName(TCppMethod_t, int iarg)
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.
std::string GetMethodArgType(TCppMethod_t, int iarg)
Bool_t IsStaticMethod(TCppMethod_t method)
void Throw(int code)
If an exception context has been set (using the TRY and RETRY macros) jump back to where it was set...
Bool_t IsConstMethod(TCppMethod_t)
virtual Int_t GetMaxArgs()
Cppyy::TCppMethod_t fMethod
R__EXTERN void * TPyCPPExceptionMagic
virtual ~TMethodHolder()
destructor
virtual Bool_t ConvertAndSetArgs(PyObject *args, TCallContext *ctxt=0)
Bool_t InitConverters_()
build buffers for argument dispatching
std::string GetMethodArgDefault(TCppMethod_t, int iarg)