Logo ROOT   6.16/01
Reference Guide
TMethodHolder.cxx
Go to the documentation of this file.
1// @(#)root/pyroot:$Id$
2// Author: Wim Lavrijsen, Apr 2004
3
4// Bindings
5#include "PyROOT.h"
6#include "TMethodHolder.h"
7#include "Converters.h"
8#include "Executors.h"
9#include "ObjectProxy.h"
10#include "RootWrapper.h"
11#include "TPyException.h"
12#include "Utility.h"
13
14// ROOT
15#include "TClass.h" // for exception types (to move to Cppyy.cxx)
16#include "TException.h" // for TRY ... CATCH
17#include "TVirtualMutex.h" // for R__LOCKGUARD2
18#include "TClassEdit.h" // demangler
19#include "TInterpreter.h" // for Interpreter exceptions
20
21// Standard
22#include <assert.h>
23#include <string.h>
24#include <exception>
25#include <sstream>
26#include <string>
27#include <typeinfo>
28#include <memory>
29
30//- data and local helpers ---------------------------------------------------
31namespace PyROOT {
33}
34
35
36//- private helpers ----------------------------------------------------------
37inline void PyROOT::TMethodHolder::Copy_( const TMethodHolder& /* other */ )
38{
39// fScope and fMethod handled separately
40
41// do not copy caches
42 fExecutor = 0;
43 fArgsRequired = -1;
44
45// being uninitialized will trigger setting up caches as appropriate
47}
48
49////////////////////////////////////////////////////////////////////////////////
50/// destroy executor and argument converters
51
53{
54 delete fExecutor;
55
56 for ( int i = 0; i < (int)fConverters.size(); ++i )
57 delete fConverters[ i ];
58}
59
60////////////////////////////////////////////////////////////////////////////////
61/// Helper code to prevent some duplication; this is called from CallSafe() as well
62/// as directly from TMethodHolder::Execute in fast mode.
63
64inline PyObject* PyROOT::TMethodHolder::CallFast( void* self, ptrdiff_t offset, TCallContext* ctxt )
65{
66 PyObject* result = nullptr;
67
68 try { // C++ try block
69 result = fExecutor->Execute( fMethod, (Cppyy::TCppObject_t)((Long_t)self + offset), ctxt );
70 } catch ( TPyException& ) {
71 result = nullptr; // error already set
72 } catch ( std::exception& e ) {
73 if (gInterpreter->DiagnoseIfInterpreterException(e)) {
74 return result;
75 }
76 // map user exceptions .. this needs to move to Cppyy.cxx
77 TClass* cl = TClass::GetClass( typeid(e) );
78
79 PyObject* pyUserExcepts = PyObject_GetAttrString( gRootModule, "UserExceptions" );
80 std::string exception_type;
81 if (cl) exception_type = cl->GetName();
82 else {
83 int errorCode;
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();
87 }
88 PyObject* pyexc = PyDict_GetItemString( pyUserExcepts, exception_type.c_str() );
89 if ( !pyexc ) {
90 PyErr_Clear();
91 pyexc = PyDict_GetItemString( pyUserExcepts, ("std::"+exception_type).c_str() );
92 }
93 if ( !pyexc ) {
94 PyErr_Clear();
95 pyexc = PyDict_GetItemString( pyUserExcepts, ("ROOT::"+exception_type).c_str() );
96 }
97 Py_DECREF( pyUserExcepts );
98
99 if ( pyexc ) {
100 PyErr_Format( pyexc, "%s", e.what() );
101 } else {
102 PyErr_Format( PyExc_Exception, "%s (C++ exception of type %s)", e.what(), exception_type.c_str() );
103 }
104 result = nullptr;
105 } catch ( ... ) {
106 PyErr_SetString( PyExc_Exception, "unhandled, unknown C++ exception" );
107 result = nullptr;
108 }
109 return result;
110}
111
112////////////////////////////////////////////////////////////////////////////////
113/// Helper code to prevent some code duplication; this code embeds a ROOT "try/catch"
114/// block that saves the stack for restoration in case of an otherwise fatal signal.
115
116inline PyObject* PyROOT::TMethodHolder::CallSafe( void* self, ptrdiff_t offset, TCallContext* ctxt )
117{
118 PyObject* result = 0;
119
120 TRY { // ROOT "try block"
121 result = CallFast( self, offset, ctxt );
122 } CATCH( excode ) {
123 PyErr_SetString( PyExc_SystemError, "problem in C++; program state has been reset" );
124 result = 0;
125 Throw( excode );
126 } ENDTRY;
127
128 return result;
129}
130
131////////////////////////////////////////////////////////////////////////////////
132/// build buffers for argument dispatching
133
135{
136 const size_t nArgs = Cppyy::GetMethodNumArgs( fMethod );
137 fConverters.resize( nArgs );
138
139// setup the dispatch cache
140 for ( size_t iarg = 0; iarg < nArgs; ++iarg ) {
141 const std::string& fullType = Cppyy::GetMethodArgType( fMethod, iarg );
142
143 // CLING WORKAROUND -- std::string can not use kExactMatch as that will
144 // fail, but if no exact match is used, the const-ref
145 // std::string arguments will mask the const char* ones,
146 // even though the extra default arguments differ
147 if ( Cppyy::GetFinalName( fScope ) == "string" && Cppyy::GetMethodName( fMethod ) == "string" &&
148 // Note with the improve naming normalization we should see only
149 // the spelling "const string&" (but soon it will be "const std::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 ); // TODO: this is sooo wrong
153 // -- CLING WORKAROUND
154 } else
155 fConverters[ iarg ] = CreateConverter( fullType );
156
157 if ( ! fConverters[ iarg ] ) {
158 PyErr_Format( PyExc_TypeError, "argument type %s not handled", fullType.c_str() );
159 return kFALSE;
160 }
161
162 }
163
164 return kTRUE;
165}
166
167////////////////////////////////////////////////////////////////////////////////
168/// install executor conform to the return type
169
171{
172 executor = CreateExecutor( (Bool_t)fMethod == true ?
174 ctxt ? ManagesSmartPtr( ctxt ) : kFALSE );
175
176 if ( ! executor )
177 return kFALSE;
178
179 return kTRUE;
180}
181
182////////////////////////////////////////////////////////////////////////////////
183/// built a signature representation (used for doc strings)
184
186{
187 std::stringstream sig; sig << "(";
188 Int_t ifirst = 0;
189 const size_t nArgs = Cppyy::GetMethodNumArgs( fMethod );
190 for ( size_t iarg = 0; iarg < nArgs; ++iarg ) {
191 if ( ifirst ) sig << ", ";
192
193 sig << Cppyy::GetMethodArgType( fMethod, iarg );
194
195 const std::string& parname = Cppyy::GetMethodArgName( fMethod, iarg );
196 if ( ! parname.empty() )
197 sig << " " << parname;
198
199 const std::string& defvalue = Cppyy::GetMethodArgDefault( fMethod, iarg );
200 if ( ! defvalue.empty() )
201 sig << " = " << defvalue;
202 ifirst++;
203 }
204 sig << ")";
205 return sig.str();
206}
207
208////////////////////////////////////////////////////////////////////////////////
209/// helper to report errors in a consistent format (derefs msg)
210
212{
213 PyObject *etype, *evalue, *etrace;
214 PyErr_Fetch( &etype, &evalue, &etrace );
215
216 std::string details = "";
217 if ( evalue ) {
218 PyObject* descr = PyObject_Str( evalue );
219 if ( descr ) {
220 details = PyROOT_PyUnicode_AsString( descr );
221 Py_DECREF( descr );
222 }
223 }
224
225 Py_XDECREF( evalue ); Py_XDECREF( etrace );
226
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 ) : "" );
232 } else if ( msg ) {
233 PyErr_Format( errtype, "%s =>\n %s (%s)",
234 PyROOT_PyUnicode_AsString( doc ), PyROOT_PyUnicode_AsString( msg ), details.c_str() );
235 } else {
236 PyErr_Format( errtype, "%s =>\n %s",
237 PyROOT_PyUnicode_AsString( doc ), details.c_str() );
238 }
239
240 Py_XDECREF( etype );
241 Py_DECREF( doc );
242 Py_XDECREF( msg );
243}
244
245//- constructors and destructor ----------------------------------------------
248 fMethod( method ), fScope( scope ), fExecutor( nullptr ), fArgsRequired( -1 ),
249 fIsInitialized( kFALSE )
250{
251 // empty
252}
253
255 PyCallable( other ), fMethod( other.fMethod ), fScope( other.fScope )
256{
257// copy constructor
258 Copy_( other );
259}
260
261////////////////////////////////////////////////////////////////////////////////
262/// assignment operator
263
265{
266 if ( this != &other ) {
267 Destroy_();
268 Copy_( other );
269 fScope = other.fScope;
270 fMethod = other.fMethod;
271 }
272
273 return *this;
274}
275
276////////////////////////////////////////////////////////////////////////////////
277/// destructor
278
280{
281 Destroy_();
282}
283
284
285//- public members -----------------------------------------------------------
287{
288// construct python string from the method's prototype
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() );
294}
295
296////////////////////////////////////////////////////////////////////////////////
297/// Method priorities exist (in lieu of true overloading) there to prevent
298/// void* or <unknown>* from usurping otherwise valid calls. TODO: extend this
299/// to favour classes that are not bases.
300
302{
303 Int_t priority = 0;
304
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 );
308
309 // the following numbers are made up and may cause problems in specific
310 // situations: use <obj>.<meth>.disp() for choice of exact dispatch
311 if ( Cppyy::IsBuiltin( aname ) ) {
312 // happens for builtin types (and namespaces, but those can never be an
313 // argument), NOT for unknown classes as that concept no longer exists
314 if ( strstr( aname.c_str(), "void*" ) )
315 // TODO: figure out in general all void* converters
316 priority -= 10000; // void*/void** shouldn't be too greedy
317 else if ( strstr( aname.c_str(), "float" ) )
318 priority -= 1000; // double preferred (no float in python)
319 else if ( strstr( aname.c_str(), "long double" ) )
320 priority -= 100; // id, but better than float
321 else if ( strstr( aname.c_str(), "double" ) )
322 priority -= 10; // char, int, long can't convert float,
323 // but vv. works, so prefer the int types
324 else if ( strstr( aname.c_str(), "bool" ) )
325 priority += 1; // bool over int (does accept 1 and 0)
326
327 } else if ( !aname.empty() && !Cppyy::IsComplete( aname ) ) {
328 // class is known, but no dictionary available, 2 more cases: * and &
329 if ( aname[ aname.size() - 1 ] == '&' )
330 priority -= 1000000;
331 else
332 priority -= 100000; // prefer pointer passing over reference
333
334 } else {
335 // resolve a few special cases (these are valid & known, but are lined up
336 // with derived classes in there interface that should have preference
337 if ( aname == "IBaseFunctionMultiDim")
338 priority -= 1;
339 else if ( aname == "RooAbsReal" )
340 priority -= 1;
341 }
342
343 }
344
345// add a small penalty to prefer non-const methods over const ones for
346// getitem/setitem
347 if ( Cppyy::IsConstMethod( fMethod ) && Cppyy::GetMethodName( fMethod ) == "operator[]" )
348 priority -= 1;
349
350// another special case for RooFit, as it is inconsistent on base <-> derived
351 if ( Cppyy::GetMethodName( fMethod ) == "import" &&
352 nArgs != 0 && Cppyy::GetMethodArgType( fMethod, 0 ) == "TObject&" )
353 priority -= 1000;
354
355 return priority;
356}
357
358////////////////////////////////////////////////////////////////////////////////
359
361{
362 return Cppyy::GetMethodNumArgs( fMethod );
363}
364
365////////////////////////////////////////////////////////////////////////////////
366/// Build a tuple of the argument types/names.
367
369{
370 int co_argcount = (int)GetMaxArgs() /* +1 for self */;
371
372// TODO: static methods need no 'self' (but is harmless otherwise)
373
374 PyObject* co_varnames = PyTuple_New( co_argcount + 1 /* self */ );
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() ) {
380 argrep += " ";
381 argrep += parname;
382 }
383
384 PyObject* pyspec = PyROOT_PyUnicode_FromString( argrep.c_str() );
385
386 PyTuple_SET_ITEM( co_varnames, iarg + 1, pyspec );
387 }
388
389 return co_varnames;
390}
391
392////////////////////////////////////////////////////////////////////////////////
393/// get the default value (if any) of argument iarg of this method
394
396{
397 if ( iarg >= (int)GetMaxArgs() )
398 return 0;
399
400 const std::string& defvalue = Cppyy::GetMethodArgDefault( fMethod, iarg );
401 if ( ! defvalue.empty() ) {
402
403 // attempt to evaluate the string representation (will work for all builtin types)
404 PyObject* pyval = (PyObject*)PyRun_String(
405 (char*)defvalue.c_str(), Py_eval_input, gRootModule, gRootModule );
406 if ( ! pyval && PyErr_Occurred() ) {
407 PyErr_Clear();
408 return PyROOT_PyUnicode_FromString( defvalue.c_str() );
409 }
410
411 return pyval;
412 }
413
414 return 0;
415}
416
417////////////////////////////////////////////////////////////////////////////////
418/// Get or build the scope of this method.
419
421{
422 return CreateScopeProxy( fScope );
423}
424
425////////////////////////////////////////////////////////////////////////////////
426/// done if cache is already setup
427
429{
430 if ( fIsInitialized == kTRUE )
431 return kTRUE;
432
433 if ( ! InitConverters_() )
434 return kFALSE;
435
436 if ( ! InitExecutor_( fExecutor, ctxt ) )
437 return kFALSE;
438
439// minimum number of arguments when calling
440 fArgsRequired = (Bool_t)fMethod == true ? Cppyy::GetMethodReqArgs( fMethod ) : 0;
441
442// init done
443 fIsInitialized = kTRUE;
444
445 return kTRUE;
446}
447
448////////////////////////////////////////////////////////////////////////////////
449/// verify existence of self, return if ok
450
452{
453 if ( self != 0 ) {
454 Py_INCREF( args );
455 return args;
456 }
457
458// otherwise, check for a suitable 'self' in args and update accordingly
459 if ( PyTuple_GET_SIZE( args ) != 0 ) {
460 ObjectProxy* pyobj = (ObjectProxy*)PyTuple_GET_ITEM( args, 0 );
461
462 // demand PyROOT object, and an argument that may match down the road
463 if ( ObjectProxy_Check( pyobj ) &&
464 ( fScope == Cppyy::gGlobalScope || // free global
465 ( pyobj->ObjectIsA() == 0 ) || // null pointer or ctor call
466 ( Cppyy::IsSubtype( pyobj->ObjectIsA(), fScope ) ) ) // matching types
467 ) {
468 // reset self
469 self = pyobj;
470 Py_INCREF( self ); // corresponding Py_DECREF is in MethodProxy
471
472 // offset args by 1 (new ref)
473 return PyTuple_GetSlice( args, 1, PyTuple_GET_SIZE( args ) );
474 }
475 }
476
477// no self, set error and lament
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() ) );
482 return 0;
483}
484
485////////////////////////////////////////////////////////////////////////////////
486
488{
489 int argc = PyTuple_GET_SIZE( args );
490 int argMax = fConverters.size();
491
492// argc must be between min and max number of arguments
493 if ( argc < fArgsRequired ) {
494 SetPyError_( PyROOT_PyUnicode_FromFormat(
495 "takes at least %d arguments (%d given)", fArgsRequired, argc ) );
496 return kFALSE;
497 } else if ( argMax < argc ) {
498 SetPyError_( PyROOT_PyUnicode_FromFormat(
499 "takes at most %d arguments (%d given)", argMax, argc ) );
500 return kFALSE;
501 }
502
503// convert the arguments to the method call array
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 ) );
509 return kFALSE;
510 }
511 }
512
513 return kTRUE;
514}
515
516////////////////////////////////////////////////////////////////////////////////
517/// call the interface method
518
519PyObject* PyROOT::TMethodHolder::Execute( void* self, ptrdiff_t offset, TCallContext* ctxt )
520{
521 PyObject* result = 0;
522
524 // bypasses ROOT try block (i.e. segfaults will abort)
525 result = CallFast( self, offset, ctxt );
526 } else {
527 // at the cost of ~10% performance, don't abort the interpreter on any signal
528 result = CallSafe( self, offset, ctxt );
529 }
530
531 if ( result && Utility::PyErr_Occurred_WithGIL() ) {
532 // can happen in the case of a CINT error: trigger exception processing
533 Py_DECREF( result );
534 result = 0;
535 } else if ( ! result && PyErr_Occurred() )
536 SetPyError_( 0 );
537
538 return result;
539}
540
541////////////////////////////////////////////////////////////////////////////////
542/// preliminary check in case keywords are accidently used (they are ignored otherwise)
543
545 ObjectProxy*& self, PyObject* args, PyObject* kwds, TCallContext* ctxt )
546{
547 if ( kwds != 0 && PyDict_Size( kwds ) ) {
548 PyErr_SetString( PyExc_TypeError, "keyword arguments are not yet supported" );
549 return 0;
550 }
551
552// setup as necessary
553 if ( ! Initialize( ctxt ) )
554 return 0; // important: 0, not Py_None
555
556// fetch self, verify, and put the arguments in usable order
557 if ( ! ( args = PreProcessArgs( self, args, kwds ) ) )
558 return 0;
559
560// translate the arguments
561 Bool_t bConvertOk = ConvertAndSetArgs( args, ctxt );
562 Py_DECREF( args );
563
564 if ( bConvertOk == kFALSE )
565 return 0; // important: 0, not Py_None
566
567// get the ROOT object that this object proxy is a handle for
568 void* object = self->GetObject();
569
570// validity check that should not fail
571 if ( ! object ) {
572 PyErr_SetString( PyExc_ReferenceError, "attempt to access a null-pointer" );
573 return 0;
574 }
575
576// get its class
577 Cppyy::TCppType_t derived = self->ObjectIsA();
578
579// calculate offset (the method expects 'this' to be an object of fScope)
580 ptrdiff_t offset = 0;
581 if ( derived && derived != fScope )
582 offset = Cppyy::GetBaseOffset( derived, fScope, object, 1 /* up-cast */ );
583
584// actual call; recycle self instead of returning new object for same address objects
585 ObjectProxy* pyobj = (ObjectProxy*)Execute( object, offset, ctxt );
586
587 if ( ObjectProxy_Check( pyobj ) &&
588 derived && pyobj->ObjectIsA() == derived &&
589 pyobj->GetObject() == object ) {
590 Py_INCREF( (PyObject*)self );
591 Py_DECREF( pyobj );
592 return (PyObject*)self;
593 }
594
595 return (PyObject*)pyobj;
596}
597
598//- protected members --------------------------------------------------------
600{
601// construct python string from the method's signature
602 return PyROOT_PyUnicode_FromString( GetSignatureString().c_str() );
603}
604
605////////////////////////////////////////////////////////////////////////////////
606
608{
609 return Cppyy::GetMethodResultType( fMethod );
610}
#define R__EXTERN
Definition: DllImport.h:27
#define PyROOT_PyUnicode_AsString
Definition: PyROOT.h:78
#define PyROOT_PyUnicode_FromString
Definition: PyROOT.h:82
#define PyROOT_PyUnicode_FromFormat
Definition: PyROOT.h:81
#define e(i)
Definition: RSha256.hxx:103
int Int_t
Definition: RtypesCore.h:41
const Bool_t kFALSE
Definition: RtypesCore.h:88
long Long_t
Definition: RtypesCore.h:50
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kTRUE
Definition: RtypesCore.h:87
#define CATCH(n)
Definition: TException.h:63
void Throw(int code)
If an exception context has been set (using the TRY and RETRY macros) jump back to where it was set.
Definition: TException.cxx:27
#define ENDTRY
Definition: TException.h:69
#define TRY
Definition: TException.h:56
#define gInterpreter
Definition: TInterpreter.h:538
_object PyObject
Definition: TPyArg.h:20
Cppyy::TCppType_t ObjectIsA() const
Definition: ObjectProxy.h:66
void * GetObject() const
Definition: ObjectProxy.h:47
virtual Int_t GetPriority()
Method priorities exist (in lieu of true overloading) there to prevent void* or <unknown>* from usurp...
virtual Bool_t Initialize(TCallContext *ctxt=0)
done if cache is already setup
virtual PyObject * GetCoVarNames()
Build a tuple of the argument types/names.
virtual PyObject * GetSignature()
virtual Int_t GetMaxArgs()
virtual ~TMethodHolder()
destructor
virtual PyObject * Execute(void *self, ptrdiff_t offset, TCallContext *ctxt=0)
call the interface method
void Copy_(const TMethodHolder &)
void SetPyError_(PyObject *msg)
helper to report errors in a consistent format (derefs msg)
TMethodHolder & operator=(const TMethodHolder &)
assignment operator
TMethodHolder(Cppyy::TCppScope_t scope, Cppyy::TCppMethod_t method)
virtual PyObject * PreProcessArgs(ObjectProxy *&self, PyObject *args, PyObject *kwds)
verify existence of self, return if ok
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::string GetSignatureString()
built a signature representation (used for doc strings)
Cppyy::TCppScope_t fScope
Definition: TMethodHolder.h:71
std::string GetReturnTypeName()
virtual PyObject * GetArgDefault(Int_t iarg)
get the default value (if any) of argument iarg of this method
virtual Bool_t ConvertAndSetArgs(PyObject *args, TCallContext *ctxt=0)
Cppyy::TCppMethod_t fMethod
Definition: TMethodHolder.h:70
void Destroy_() const
destroy executor and argument converters
PyObject * CallFast(void *, ptrdiff_t, TCallContext *)
Helper code to prevent some duplication; this is called from CallSafe() as well as directly from TMet...
Bool_t InitConverters_()
build buffers for argument dispatching
virtual PyObject * GetPrototype()
virtual Bool_t InitExecutor_(TExecutor *&, TCallContext *ctxt=0)
install executor conform to the return type
PyObject * CallSafe(void *, ptrdiff_t, TCallContext *)
Helper code to prevent some code duplication; this code embeds a ROOT "try/catch" block that saves th...
virtual PyObject * GetScopeProxy()
Get or build the scope of this method.
The ROOT global object gROOT contains a list of all defined classes.
Definition: TClass.h:75
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.
Definition: TClass.cxx:2885
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
ptrdiff_t GetBaseOffset(TCppType_t derived, TCppType_t base, TCppObject_t address, int direction, bool rerror=false)
Definition: Cppyy.cxx:637
ptrdiff_t TCppScope_t
Definition: Cppyy.h:15
std::string GetMethodArgType(TCppMethod_t, int iarg)
Definition: Cppyy.cxx:798
std::string GetMethodName(TCppMethod_t)
Definition: Cppyy.cxx:750
TCppIndex_t GetMethodReqArgs(TCppMethod_t)
Definition: Cppyy.cxx:779
TCppScope_t gGlobalScope
Definition: Cppyy.cxx:64
std::string ResolveName(const std::string &cppitem_name)
Definition: Cppyy.cxx:167
TCppScope_t TCppType_t
Definition: Cppyy.h:16
Bool_t IsComplete(const std::string &type_name)
Definition: Cppyy.cxx:249
std::string GetScopedFinalName(TCppType_t type)
Definition: Cppyy.cxx:587
Bool_t IsConstMethod(TCppMethod_t)
Definition: Cppyy.cxx:826
std::string GetMethodArgDefault(TCppMethod_t, int iarg)
Definition: Cppyy.cxx:808
TCppIndex_t GetMethodNumArgs(TCppMethod_t)
Definition: Cppyy.cxx:772
TCppScope_t GetScope(const std::string &scope_name)
Definition: Cppyy.cxx:193
Bool_t IsStaticMethod(TCppMethod_t method)
Definition: Cppyy.cxx:883
std::string GetMethodArgName(TCppMethod_t, int iarg)
Definition: Cppyy.cxx:788
ptrdiff_t TCppMethod_t
Definition: Cppyy.h:18
Bool_t IsBuiltin(const std::string &type_name)
Definition: Cppyy.cxx:242
std::string GetMethodResultType(TCppMethod_t)
Definition: Cppyy.cxx:761
std::string GetFinalName(TCppType_t type)
Definition: Cppyy.cxx:578
void * TCppObject_t
Definition: Cppyy.h:17
Bool_t IsSubtype(TCppType_t derived, TCppType_t base)
Definition: Cppyy.cxx:615
PyObject * PyErr_Occurred_WithGIL()
Re-acquire the GIL before calling PyErr_Occurred() in case it has been released; note that the p2....
Definition: Utility.cxx:902
TExecutor * CreateExecutor(const std::string &fullType, Bool_t manage_smart_ptr=kTRUE)
Definition: Executors.cxx:637
Bool_t ObjectProxy_Check(T *object)
Definition: ObjectProxy.h:91
PyObject * CreateScopeProxy(Cppyy::TCppScope_t)
Convenience function with a lookup first through the known existing proxies.
TConverter * CreateConverter(const std::string &fullType, Long_t size=-1)
R__EXTERN PyObject * gRootModule
Definition: ObjectProxy.cxx:39
Bool_t ManagesSmartPtr(TCallContext *ctxt)
Definition: TCallContext.h:73
char * DemangleTypeIdName(const std::type_info &ti, int &errorCode)
Demangle in a portable way the type id name.
void Initialize(Bool_t useTMVAStyle=kTRUE)
Definition: tmvaglob.cxx:176
std::vector< TParameter > fArgs
Definition: TCallContext.h:57
static ECallFlags sSignalPolicy
Definition: TCallContext.h:53