18 #include "TClassEdit.h" 56 for (
int i = 0; i < (int)fConverters.size(); ++i )
57 delete fConverters[ i ];
72 }
catch ( std::exception&
e ) {
80 std::string exception_type;
81 if (cl) exception_type = cl->
GetName();
84 std::unique_ptr<char[]> demangled(TClassEdit::DemangleTypeIdName(
typeid(e),errorCode));
85 if (errorCode) exception_type =
typeid(
e).
name();
86 else exception_type = demangled.get();
88 PyObject* pyexc = PyDict_GetItemString( pyUserExcepts, exception_type.c_str() );
91 pyexc = PyDict_GetItemString( pyUserExcepts, (
"std::"+exception_type).c_str() );
95 pyexc = PyDict_GetItemString( pyUserExcepts, (
"ROOT::"+exception_type).c_str() );
97 Py_DECREF( pyUserExcepts );
100 PyErr_Format( pyexc,
"%s", e.what() );
102 PyErr_Format( PyExc_Exception,
"%s (C++ exception of type %s)", e.what(), exception_type.c_str() );
106 PyErr_SetString( PyExc_Exception,
"unhandled, unknown C++ exception" );
121 result = CallFast(
self, offset, ctxt );
123 PyErr_SetString( PyExc_SystemError,
"problem in C++; program state has been reset" );
137 fConverters.resize( nArgs );
140 for (
size_t iarg = 0; iarg < nArgs; ++iarg ) {
150 ( fullType ==
"const std::string&" || fullType ==
"const std::string &" 151 || fullType ==
"const string&" || fullType ==
"const string &" ) ) {
157 if ( ! fConverters[ iarg ] ) {
158 PyErr_Format( PyExc_TypeError,
"argument type %s not handled", fullType.c_str() );
187 std::stringstream sig; sig <<
"(";
190 for (
size_t iarg = 0; iarg < nArgs; ++iarg ) {
191 if ( ifirst ) sig <<
", ";
196 if ( ! parname.empty() )
197 sig <<
" " << parname;
200 if ( ! defvalue.empty() )
201 sig <<
" = " << defvalue;
214 PyErr_Fetch( &etype, &evalue, &etrace );
216 std::string details =
"";
218 PyObject* descr = PyObject_Str( evalue );
225 Py_XDECREF( evalue ); Py_XDECREF( etrace );
228 PyObject* errtype = etype ? etype : PyExc_TypeError;
229 if ( details.empty() ) {
233 PyErr_Format( errtype,
"%s =>\n %s (%s)",
236 PyErr_Format( errtype,
"%s =>\n %s",
248 fMethod( method ), fScope( scope ), fExecutor( nullptr ), fArgsRequired( -1 ),
266 if (
this != &other ) {
306 for (
size_t iarg = 0; iarg < nArgs; ++iarg ) {
314 if ( strstr( aname.c_str(),
"void*" ) )
317 else if ( strstr( aname.c_str(),
"float" ) )
319 else if ( strstr( aname.c_str(),
"long double" ) )
321 else if ( strstr( aname.c_str(),
"double" ) )
324 else if ( strstr( aname.c_str(),
"bool" ) )
329 if ( aname[ aname.size() - 1 ] ==
'&' )
337 if ( aname ==
"IBaseFunctionMultiDim")
339 else if ( aname ==
"RooAbsReal" )
374 PyObject* co_varnames = PyTuple_New( co_argcount + 1 );
376 for (
int iarg = 0; iarg < co_argcount; ++iarg ) {
379 if ( ! parname.empty() ) {
386 PyTuple_SET_ITEM( co_varnames, iarg + 1, pyspec );
401 if ( ! defvalue.empty() ) {
406 if ( ! pyval && PyErr_Occurred() ) {
459 if ( PyTuple_GET_SIZE( args ) != 0 ) {
473 return PyTuple_GetSlice( args, 1, PyTuple_GET_SIZE( args ) );
479 "unbound method %s::%s must be called with a %s instance as first argument",
489 int argc = PyTuple_GET_SIZE( args );
495 "takes at least %d arguments (%d given)",
fArgsRequired, argc ) );
497 }
else if ( argMax < argc ) {
499 "takes at most %d arguments (%d given)", argMax, argc ) );
504 ctxt->
fArgs.resize( argc );
505 for (
int i = 0; i < argc; ++i ) {
507 PyTuple_GET_ITEM( args, i ), ctxt->
fArgs[i], ctxt ) ) {
525 result =
CallFast(
self, offset, ctxt );
528 result =
CallSafe(
self, offset, ctxt );
535 }
else if ( ! result && PyErr_Occurred() )
547 if ( kwds != 0 && PyDict_Size( kwds ) ) {
548 PyErr_SetString( PyExc_TypeError,
"keyword arguments are not yet supported" );
564 if ( bConvertOk ==
kFALSE )
568 void*
object =
self->GetObject();
572 PyErr_SetString( PyExc_ReferenceError,
"attempt to access a null-pointer" );
580 ptrdiff_t offset = 0;
581 if ( derived && derived !=
fScope )
588 derived && pyobj->
ObjectIsA() == derived &&
virtual const char * GetName() const
Returns name of object.
#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.
#define PyROOT_PyUnicode_FromFormat
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...
#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)
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)
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)
std::vector< TConverter *> fConverters
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...
you should not use this method at all Int_t Int_t Double_t Double_t Double_t e
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
void Destroy_() const
destroy executor and argument converters
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)
Cppyy::TCppType_t ObjectIsA() const