32    R__EXTERN PyObject* gRootModule;
 
   37 inline void PyROOT::TMethodHolder::Copy_( 
const TMethodHolder&  )
 
   46    fIsInitialized  = kFALSE;
 
   52 inline void PyROOT::TMethodHolder::Destroy_()
 const 
   56    for ( 
int i = 0; i < (int)fConverters.size(); ++i )
 
   57       delete fConverters[ i ];
 
   64 inline PyObject* PyROOT::TMethodHolder::CallFast( 
void* 
self, ptrdiff_t offset, TCallContext* ctxt )
 
   66    PyObject* result = 
nullptr;
 
   69       result = fExecutor->Execute( fMethod, (Cppyy::TCppObject_t)((Long_t)
self + offset), ctxt );
 
   70    } 
catch ( TPyException& ) {
 
   72    } 
catch ( std::exception& e ) {
 
   73       if (gInterpreter->DiagnoseIfInterpreterException(e)) {
 
   77       TClass* cl = TClass::GetClass( 
typeid(e) );
 
   79       PyObject* pyUserExcepts = PyObject_GetAttrString( gRootModule, 
"UserExceptions" );
 
   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" );
 
  116 inline PyObject* PyROOT::TMethodHolder::CallSafe( 
void* 
self, ptrdiff_t offset, TCallContext* ctxt )
 
  118    PyObject* result = 0;
 
  121       result = CallFast( 
self, offset, ctxt );
 
  123       PyErr_SetString( PyExc_SystemError, 
"problem in C++; program state has been reset" );
 
  134 Bool_t PyROOT::TMethodHolder::InitConverters_()
 
  136    const size_t nArgs = Cppyy::GetMethodNumArgs( fMethod );
 
  137    fConverters.resize( nArgs );
 
  140    for ( 
size_t iarg = 0; iarg < nArgs; ++iarg ) {
 
  141       const std::string& fullType = Cppyy::GetMethodArgType( fMethod, iarg );
 
  147       if ( Cppyy::GetFinalName( fScope ) == 
"string" && Cppyy::GetMethodName( fMethod ) == 
"string" &&
 
  150            ( fullType == 
"const std::string&" || fullType == 
"const std::string &" 
  151              || fullType == 
"const string&" || fullType == 
"const string &" ) ) {
 
  152          fConverters[ iarg ] = 
new TStrictCppObjectConverter( Cppyy::GetScope( 
"string" ), kFALSE ); 
 
  155          fConverters[ iarg ] = CreateConverter( fullType );
 
  157       if ( ! fConverters[ iarg ] ) {
 
  158          PyErr_Format( PyExc_TypeError, 
"argument type %s not handled", fullType.c_str() );
 
  170 Bool_t PyROOT::TMethodHolder::InitExecutor_( TExecutor*& executor, TCallContext* ctxt )
 
  172    executor = CreateExecutor( (Bool_t)fMethod == 
true ?
 
  173       Cppyy::ResolveName( Cppyy::GetMethodResultType( fMethod ) ) : Cppyy::GetScopedFinalName( fScope ),
 
  174       ctxt ? ManagesSmartPtr( ctxt ) : kFALSE );
 
  185 std::string PyROOT::TMethodHolder::GetSignatureString()
 
  187    std::stringstream sig; sig << 
"(";
 
  189    const size_t nArgs = Cppyy::GetMethodNumArgs( fMethod );
 
  190    for ( 
size_t iarg = 0; iarg < nArgs; ++iarg ) {
 
  191       if ( ifirst ) sig << 
", ";
 
  193       sig << Cppyy::GetMethodArgType( fMethod, iarg );
 
  195       const std::string& parname = Cppyy::GetMethodArgName( fMethod, iarg );
 
  196       if ( ! parname.empty() )
 
  197          sig << 
" " << parname;
 
  199       const std::string& defvalue = Cppyy::GetMethodArgDefault( fMethod, iarg );
 
  200       if ( ! defvalue.empty() )
 
  201          sig << 
" = " << defvalue;
 
  211 void PyROOT::TMethodHolder::SetPyError_( PyObject* msg )
 
  213    PyObject *etype, *evalue, *etrace;
 
  214    PyErr_Fetch( &etype, &evalue, &etrace );
 
  216    std::string details = 
"";
 
  218       PyObject* descr = PyObject_Str( evalue );
 
  220          details = PyROOT_PyUnicode_AsString( descr );
 
  225    Py_XDECREF( evalue ); Py_XDECREF( etrace );
 
  227    PyObject* doc = GetDocString();
 
  228    PyObject* errtype = etype ? etype : PyExc_TypeError;
 
  229    if ( details.empty() ) {
 
  230       PyErr_Format( errtype, 
"%s =>\n    %s", PyROOT_PyUnicode_AsString( doc ),
 
  231          msg ? PyROOT_PyUnicode_AsString( msg ) : 
""  );
 
  233       PyErr_Format( errtype, 
"%s =>\n    %s (%s)",
 
  234          PyROOT_PyUnicode_AsString( doc ), PyROOT_PyUnicode_AsString( msg ), details.c_str() );
 
  236       PyErr_Format( errtype, 
"%s =>\n    %s",
 
  237          PyROOT_PyUnicode_AsString( doc ), details.c_str() );
 
  246 PyROOT::TMethodHolder::TMethodHolder(
 
  247       Cppyy::TCppScope_t scope, Cppyy::TCppMethod_t method ) :
 
  248    fMethod( method ), fScope( scope ), fExecutor( nullptr ), fArgsRequired( -1 ),
 
  249    fIsInitialized( kFALSE )
 
  254 PyROOT::TMethodHolder::TMethodHolder( 
const TMethodHolder& other ) :
 
  255       PyCallable( other ), fMethod( other.fMethod ), fScope( other.fScope )
 
  264 PyROOT::TMethodHolder& PyROOT::TMethodHolder::operator=( 
const TMethodHolder& other )
 
  266    if ( 
this != &other ) {
 
  269       fScope  = other.fScope;
 
  270       fMethod = other.fMethod;
 
  279 PyROOT::TMethodHolder::~TMethodHolder()
 
  286 PyObject* PyROOT::TMethodHolder::GetPrototype()
 
  289    return PyROOT_PyUnicode_FromFormat( 
"%s%s %s::%s%s",
 
  290       ( Cppyy::IsStaticMethod( fMethod ) ? 
"static " : 
"" ),
 
  291       Cppyy::GetMethodResultType( fMethod ).c_str(),
 
  292       Cppyy::GetFinalName( fScope ).c_str(), Cppyy::GetMethodName( fMethod ).c_str(),
 
  293       GetSignatureString().c_str() );
 
  301 Int_t PyROOT::TMethodHolder::GetPriority()
 
  305    const size_t nArgs = Cppyy::GetMethodNumArgs( fMethod );
 
  306    for ( 
size_t iarg = 0; iarg < nArgs; ++iarg ) {
 
  307       const std::string aname = Cppyy::GetMethodArgType( fMethod, iarg );
 
  311       if ( Cppyy::IsBuiltin( aname ) ) {
 
  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" ) )
 
  327       } 
else if ( !aname.empty() && !Cppyy::IsComplete( aname ) ) {
 
  329          if ( aname[ aname.size() - 1 ] == 
'&' )
 
  337          if ( aname == 
"IBaseFunctionMultiDim")
 
  339          else if ( aname == 
"RooAbsReal" )
 
  347    if ( Cppyy::IsConstMethod( fMethod ) && Cppyy::GetMethodName( fMethod ) == 
"operator[]" )
 
  351    if ( Cppyy::GetMethodName( fMethod ) == 
"import" &&
 
  352         nArgs != 0 && Cppyy::GetMethodArgType( fMethod, 0 ) == 
"TObject&" )
 
  360 Int_t PyROOT::TMethodHolder::GetMaxArgs()
 
  362    return Cppyy::GetMethodNumArgs( fMethod );
 
  368 PyObject* PyROOT::TMethodHolder::GetCoVarNames()
 
  370    int co_argcount = (int)GetMaxArgs() ;
 
  374    PyObject* co_varnames = PyTuple_New( co_argcount + 1  );
 
  375    PyTuple_SET_ITEM( co_varnames, 0, PyROOT_PyUnicode_FromString( 
"self" ) );
 
  376    for ( 
int iarg = 0; iarg < co_argcount; ++iarg ) {
 
  377       std::string argrep = Cppyy::GetMethodArgType( fMethod, iarg );
 
  378       const std::string& parname = Cppyy::GetMethodArgName( fMethod, iarg );
 
  379       if ( ! parname.empty() ) {
 
  384       PyObject* pyspec = PyROOT_PyUnicode_FromString( argrep.c_str() );
 
  386       PyTuple_SET_ITEM( co_varnames, iarg + 1, pyspec );
 
  395 PyObject* PyROOT::TMethodHolder::GetArgDefault( Int_t iarg )
 
  397    if ( iarg >= (
int)GetMaxArgs() )
 
  400    const std::string& defvalue = Cppyy::GetMethodArgDefault( fMethod, iarg );
 
  401    if ( ! defvalue.empty() ) {
 
  404       PyObject* pyval = (PyObject*)PyRun_String(
 
  405           (
char*)defvalue.c_str(), Py_eval_input, gRootModule, gRootModule );
 
  406       if ( ! pyval && PyErr_Occurred() ) {
 
  408          return PyROOT_PyUnicode_FromString( defvalue.c_str() );
 
  420 PyObject* PyROOT::TMethodHolder::GetScopeProxy()
 
  422    return CreateScopeProxy( fScope );
 
  428 Bool_t PyROOT::TMethodHolder::Initialize( TCallContext* ctxt )
 
  430    if ( fIsInitialized == kTRUE )
 
  433    if ( ! InitConverters_() )
 
  436    if ( ! InitExecutor_( fExecutor, ctxt ) )
 
  440    fArgsRequired = (Bool_t)fMethod == 
true ? Cppyy::GetMethodReqArgs( fMethod ) : 0;
 
  443    fIsInitialized = kTRUE;
 
  451 PyObject* PyROOT::TMethodHolder::PreProcessArgs( ObjectProxy*& 
self, PyObject* args, PyObject* )
 
  459    if ( PyTuple_GET_SIZE( args ) != 0 ) {
 
  460       ObjectProxy* pyobj = (ObjectProxy*)PyTuple_GET_ITEM( args, 0 );
 
  463       if ( ObjectProxy_Check( pyobj ) &&
 
  464            ( fScope == Cppyy::gGlobalScope ||               
 
  465            ( pyobj->ObjectIsA() == 0 )     ||               
 
  466            ( Cppyy::IsSubtype( pyobj->ObjectIsA(), fScope ) ) ) 
 
  473          return PyTuple_GetSlice( args, 1, PyTuple_GET_SIZE( args ) );
 
  478    SetPyError_( PyROOT_PyUnicode_FromFormat(
 
  479       "unbound method %s::%s must be called with a %s instance as first argument",
 
  480       Cppyy::GetFinalName( fScope ).c_str(), Cppyy::GetMethodName( fMethod ).c_str(),
 
  481       Cppyy::GetFinalName( fScope ).c_str() ) );
 
  487 Bool_t PyROOT::TMethodHolder::ConvertAndSetArgs( PyObject* args, TCallContext* ctxt )
 
  489    int argc = PyTuple_GET_SIZE( args );
 
  490    int argMax = fConverters.size();
 
  493    if ( argc < fArgsRequired ) {
 
  494       SetPyError_( PyROOT_PyUnicode_FromFormat(
 
  495          "takes at least %d arguments (%d given)", fArgsRequired, argc ) );
 
  497    } 
else if ( argMax < argc ) {
 
  498       SetPyError_( PyROOT_PyUnicode_FromFormat(
 
  499          "takes at most %d arguments (%d given)", argMax, argc ) );
 
  504    ctxt->fArgs.resize( argc );
 
  505    for ( 
int i = 0; i < argc; ++i ) {
 
  506       if ( ! fConverters[ i ]->SetArg(
 
  507               PyTuple_GET_ITEM( args, i ), ctxt->fArgs[i], ctxt ) ) {
 
  508          SetPyError_( PyROOT_PyUnicode_FromFormat( 
"could not convert argument %d", i+1 ) );
 
  519 PyObject* PyROOT::TMethodHolder::Execute( 
void* 
self, ptrdiff_t offset, TCallContext* ctxt )
 
  521    PyObject* result = 0;
 
  523    if ( TCallContext::sSignalPolicy == TCallContext::kFast ) {
 
  525       result = CallFast( 
self, offset, ctxt );
 
  528       result = CallSafe( 
self, offset, ctxt );
 
  531    if ( result && Utility::PyErr_Occurred_WithGIL() ) {
 
  535    } 
else if ( ! result && PyErr_Occurred() )
 
  544 PyObject* PyROOT::TMethodHolder::Call(
 
  545       ObjectProxy*& 
self, PyObject* args, PyObject* kwds, TCallContext* ctxt )
 
  547    if ( kwds != 0 && PyDict_Size( kwds ) ) {
 
  548       PyErr_SetString( PyExc_TypeError, 
"keyword arguments are not yet supported" );
 
  553    if ( ! Initialize( ctxt ) )
 
  557    if ( ! ( args = PreProcessArgs( 
self, args, kwds ) ) )
 
  561    Bool_t bConvertOk = ConvertAndSetArgs( args, ctxt );
 
  564    if ( bConvertOk == kFALSE )
 
  568    void* 
object = 
self->GetObject();
 
  572       PyErr_SetString( PyExc_ReferenceError, 
"attempt to access a null-pointer" );
 
  577    Cppyy::TCppType_t derived = 
self->ObjectIsA();
 
  580    ptrdiff_t offset = 0;
 
  581    if ( derived && derived != fScope )
 
  582       offset = Cppyy::GetBaseOffset( derived, fScope, 
object, 1  );
 
  585    ObjectProxy* pyobj = (ObjectProxy*)Execute( 
object, offset, ctxt );
 
  587    if ( ObjectProxy_Check( pyobj ) &&
 
  588         derived && pyobj->ObjectIsA() == derived &&
 
  589         pyobj->GetObject() == object ) {
 
  590       Py_INCREF( (PyObject*)
self );
 
  592       return (PyObject*)
self;
 
  595    return (PyObject*)pyobj;
 
  599 PyObject* PyROOT::TMethodHolder::GetSignature()
 
  602    return PyROOT_PyUnicode_FromString( GetSignatureString().c_str() );
 
  607 std::string PyROOT::TMethodHolder::GetReturnTypeName()
 
  609    return Cppyy::GetMethodResultType( fMethod );