6#include "structmember.h"     
    7#if PY_VERSION_HEX >= 0x02050000 
   14#define CO_NOFREE       0x0040 
   30   class TPythonCallback : 
public PyCallable {
 
   34      TPythonCallback( 
PyObject* callable ):
 
   37         if ( !PyCallable_Check( callable ) ) {
 
   38            PyErr_SetString(PyExc_TypeError, 
"parameter must be callable");
 
   42         Py_INCREF( fCallable );
 
   45      virtual ~TPythonCallback() {
 
   46         Py_DECREF( fCallable );
 
   53         if ( PyObject_HasAttrString( fCallable, 
"__doc__" )) {
 
   54            return PyObject_GetAttrString( fCallable, 
"__doc__" );
 
   56            return GetPrototype();
 
   60      virtual Int_t GetPriority() { 
return 100; };
 
   62      virtual Int_t GetMaxArgs() { 
return 100; };
 
   77      virtual PyCallable* Clone() { 
return new TPythonCallback( *
this ); }
 
   85            newArgs = PyTuple_New( nargs+1 );
 
   87            PyTuple_SET_ITEM( newArgs, 0, (
PyObject*)self );
 
   88            for ( 
Py_ssize_t iarg = 0; iarg < nargs; ++iarg ) {
 
   89               PyObject* pyarg = PyTuple_GET_ITEM( args, iarg );
 
   91               PyTuple_SET_ITEM( newArgs, iarg+1, pyarg );
 
   97         return PyObject_Call( fCallable, newArgs, kwds );
 
  104   Bool_t inline IsPseudoFunc( MethodProxy* pymeth )
 
  106      return (
void*)pymeth == (
void*)pymeth->fSelf;
 
  113      static void Clear( PyError_t& 
e )
 
  116         Py_XDECREF( 
e.fType ); Py_XDECREF( 
e.fValue ); Py_XDECREF( 
e.fTrace );
 
  117         e.fType = 
e.fValue = 
e.fTrace = 0;
 
  129      Int_t nargs = PyTuple_GET_SIZE( args );
 
  130      for ( 
Int_t i = 0; i < nargs; ++i ) {
 
  132         hash += (hash << 10); hash ^= (hash >> 6);
 
  135      hash += (hash << 3); hash ^= (hash >> 11); hash += (hash << 15);
 
  141   int PriorityCmp( PyCallable* left, PyCallable* right )
 
  143      return left->GetPriority() > right->GetPriority();
 
  147   inline void ResetCallState( ObjectProxy*& selfnew, ObjectProxy* selfold, 
Bool_t clear ) {
 
  148      if ( selfnew != selfold ) {
 
  149         Py_XDECREF( selfnew );
 
  158   inline PyObject* HandleReturn( MethodProxy* pymeth, ObjectProxy* oldSelf, 
PyObject* result ) {
 
  164         if ( 
IsCreator( pymeth->fMethodInfo->fFlags ) ) {
 
  169                  pymeth->fSelf->HoldOn();
 
  174               ((ObjectProxy*)result)->HoldOn();
 
  179            Long_t ptrdiff = (
Long_t)((ObjectProxy*)result)->GetObject() - (
Long_t)pymeth->fSelf->GetObject();
 
  188      ResetCallState( pymeth->fSelf, oldSelf, 
kFALSE );
 
  195   PyObject* mp_name( MethodProxy* pymeth, 
void* )
 
  202   PyObject* mp_module( MethodProxy* , 
void* )
 
  211   PyObject* mp_doc( MethodProxy* pymeth, 
void* )
 
  216      Int_t nMethods = methods.size();
 
  222      PyObject* doc = methods[0]->GetDocString();
 
  230      for ( 
Int_t i = 1; i < nMethods; ++i ) {
 
  234      Py_DECREF( separator );
 
  242   PyObject* mp_meth_func( MethodProxy* pymeth, 
void* )
 
  247      *pymeth->fMethodInfo->fRefCount += 1;
 
  248      newPyMeth->fMethodInfo = pymeth->fMethodInfo;
 
  252      newPyMeth->fSelf = (ObjectProxy*)newPyMeth;
 
  261   PyObject* mp_meth_self( MethodProxy* pymeth, 
void* )
 
  263      if ( IsPseudoFunc( pymeth ) ) {
 
  264         PyErr_Format( PyExc_AttributeError,
 
  265            "function %s has no attribute \'im_self\'", pymeth->fMethodInfo->fName.c_str() );
 
  267      } 
else if ( pymeth->fSelf != 0 ) {
 
  268         Py_INCREF( (
PyObject*)pymeth->fSelf );
 
  272      Py_INCREF( Py_None );
 
  280   PyObject* mp_meth_class( MethodProxy* pymeth, 
void* )
 
  282      if ( ! IsPseudoFunc( pymeth ) ) {
 
  283         PyObject* pyclass = pymeth->fMethodInfo->fMethods[0]->GetScopeProxy();
 
  285            PyErr_Format( PyExc_AttributeError,
 
  286               "function %s has no attribute \'im_class\'", pymeth->fMethodInfo->fName.c_str() );
 
  290      Py_INCREF( Py_None );
 
  297   PyObject* mp_func_closure( MethodProxy* , 
void* )
 
  299      Py_INCREF( Py_None );
 
  306   PyObject* mp_func_code( MethodProxy* pymeth, 
void* )
 
  308#if PY_VERSION_HEX < 0x03000000 
  313      PyObject* co_varnames = methods.size() == 1 ? methods[0]->GetCoVarNames() : NULL;
 
  314      if ( !co_varnames ) {
 
  316         co_varnames = PyTuple_New( 1  + 1  );
 
  321      int co_argcount = PyTuple_Size( co_varnames );
 
  324      PyObject* co_code = PyString_FromStringAndSize( 
"d\x00\x00S", 4 );
 
  327      PyObject* co_consts = PyTuple_New( 0 );
 
  328      PyObject* co_names = PyTuple_New( 0 );
 
  331      PyObject* co_unused = PyTuple_New( 0 );
 
  334      PyObject* co_filename = PyString_FromString( 
"ROOT.py" );
 
  337      PyObject* co_name = PyString_FromString( pymeth->GetName().c_str() );
 
  342      PyObject* co_lnotab = PyString_FromString( 
"\x00\x01\x0c\x01" );
 
  360      Py_DECREF( co_lnotab );
 
  361      Py_DECREF( co_name );
 
  362      Py_DECREF( co_unused );
 
  363      Py_DECREF( co_filename );
 
  364      Py_DECREF( co_varnames );
 
  365      Py_DECREF( co_names );
 
  366      Py_DECREF( co_consts );
 
  367      Py_DECREF( co_code );
 
  373      if ( pymeth || !pymeth) Py_INCREF( Py_None );
 
  382   PyObject* mp_func_defaults( MethodProxy* pymeth, 
void* )
 
  386      if ( methods.size() != 1 )
 
  387         return PyTuple_New( 0 );
 
  389      int maxarg = methods[0]->GetMaxArgs();
 
  391      PyObject* defaults = PyTuple_New( maxarg );
 
  394      for ( 
int iarg = 0; iarg < maxarg; ++iarg ) {
 
  395         PyObject* defvalue = methods[0]->GetArgDefault( iarg );
 
  397            PyTuple_SET_ITEM( defaults, itup++, defvalue );
 
  399      _PyTuple_Resize( &defaults, itup );
 
  408   PyObject* mp_func_globals( MethodProxy* , 
void* )
 
  410      PyObject* pyglobal = PyModule_GetDict( PyImport_AddModule( (
char*)
"ROOT" ) );
 
  411      Py_XINCREF( pyglobal );
 
  418   PyObject* mp_getcreates( MethodProxy* pymeth, 
void* )
 
  420      return PyInt_FromLong( (
Bool_t)
IsCreator( pymeth->fMethodInfo->fFlags ) );
 
  426   int mp_setcreates( MethodProxy* pymeth, 
PyObject* value, 
void* )
 
  429         pymeth->fMethodInfo->fFlags &= ~TCallContext::kIsCreator;
 
  433      Long_t iscreator = PyLong_AsLong( value );
 
  434      if ( iscreator == -1 && PyErr_Occurred() ) {
 
  435         PyErr_SetString( PyExc_ValueError, 
"a boolean 1 or 0 is required for _creates" );
 
  442         pymeth->fMethodInfo->fFlags &= ~TCallContext::kIsCreator;
 
  450   PyObject* mp_getmempolicy( MethodProxy* pymeth, 
void* )
 
  458      return PyInt_FromLong( -1 );
 
  464   int mp_setmempolicy( MethodProxy* pymeth, 
PyObject* value, 
void* )
 
  466      Long_t mempolicy = PyLong_AsLong( value );
 
  469         pymeth->fMethodInfo->fFlags &= ~TCallContext::kUseStrict;
 
  472         pymeth->fMethodInfo->fFlags &= ~TCallContext::kUseHeuristics;
 
  474         PyErr_SetString( PyExc_ValueError,
 
  475            "expected kMemoryStrict or kMemoryHeuristics as value for _mempolicy" );
 
  486   PyObject* mp_get_manage_smart_ptr( MethodProxy* pymeth, 
void* )
 
  488      return PyInt_FromLong(
 
  496   int mp_set_manage_smart_ptr( MethodProxy* pymeth, 
PyObject* value, 
void* )
 
  498      Long_t policy = PyLong_AsLong( value );
 
  499      if ( policy == -1 && PyErr_Occurred() ) {
 
  500         PyErr_SetString( PyExc_ValueError, 
"a boolean 1 or 0 is required for _manage_smart_ptr" );
 
  512   PyObject* mp_getthreaded( MethodProxy* pymeth, 
void* )
 
  514      return PyInt_FromLong(
 
  521   int mp_setthreaded( MethodProxy* pymeth, 
PyObject* value, 
void* )
 
  523      Long_t isthreaded = PyLong_AsLong( value );
 
  524      if ( isthreaded == -1 && PyErr_Occurred() ) {
 
  525         PyErr_SetString( PyExc_ValueError, 
"a boolean 1 or 0 is required for _creates" );
 
  532         pymeth->fMethodInfo->fFlags &= ~TCallContext::kReleaseGIL;
 
  539   PyGetSetDef mp_getset[] = {
 
  540      { (
char*)
"__name__",   (getter)mp_name,   NULL, NULL, NULL },
 
  541      { (
char*)
"__module__", (getter)mp_module, NULL, NULL, NULL },
 
  542      { (
char*)
"__doc__",    (getter)mp_doc,    NULL, NULL, NULL },
 
  547      { (
char*)
"im_func",  (getter)mp_meth_func,  NULL, NULL, NULL },
 
  548      { (
char*)
"im_self",  (getter)mp_meth_self,  NULL, NULL, NULL },
 
  549      { (
char*)
"im_class", (getter)mp_meth_class, NULL, NULL, NULL },
 
  551      { (
char*)
"func_closure",  (getter)mp_func_closure,  NULL, NULL, NULL },
 
  552      { (
char*)
"func_code",     (getter)mp_func_code,     NULL, NULL, NULL },
 
  553      { (
char*)
"func_defaults", (getter)mp_func_defaults, NULL, NULL, NULL },
 
  554      { (
char*)
"func_globals",  (getter)mp_func_globals,  NULL, NULL, NULL },
 
  555      { (
char*)
"func_doc",      (getter)mp_doc,           NULL, NULL, NULL },
 
  556      { (
char*)
"func_name",     (getter)mp_name,          NULL, NULL, NULL },
 
  558      { (
char*)
"_creates", (getter)mp_getcreates, (setter)mp_setcreates,
 
  559            (
char*)
"For ownership rules of result: if true, objects are python-owned", NULL },
 
  560      { (
char*)
"__creates__", (getter)mp_getcreates, (setter)mp_setcreates,
 
  561            (
char*)
"For ownership rules of result: if true, objects are python-owned", NULL },
 
  562      { (
char*)
"_mempolicy", (getter)mp_getmempolicy, (setter)mp_setmempolicy,
 
  563            (
char*)
"For argument ownership rules: like global, either heuristic or strict", NULL },
 
  564      { (
char*)
"__mempolicy__", (getter)mp_getmempolicy, (setter)mp_setmempolicy,
 
  565            (
char*)
"For argument ownership rules: like global, either heuristic or strict", NULL },
 
  566      { (
char*)
"_manage_smart_ptr", (getter)mp_get_manage_smart_ptr, (setter)mp_set_manage_smart_ptr,
 
  567        (
char*)
"If a smart pointer is returned, determines management policy.", NULL },
 
  568      { (
char*)
"_threaded", (getter)mp_getthreaded, (setter)mp_setthreaded,
 
  569            (
char*)
"If true, releases GIL on call into C++", NULL },
 
  570      { (
char*)
"__release_gil__", (getter)mp_getthreaded, (setter)mp_setthreaded,
 
  571            (
char*)
"If true, releases GIL on call into C++", NULL },
 
  572      { (
char*)NULL, NULL, NULL, NULL, NULL }
 
  582      if ( IsPseudoFunc( pymeth ) )
 
  583         pymeth->fSelf = NULL;
 
  585      ObjectProxy* oldSelf = pymeth->fSelf;
 
  588      auto& methods     = pymeth->fMethodInfo->fMethods;
 
  589      auto& dispatchMap = pymeth->fMethodInfo->fDispatchMap;
 
  590      auto& mflags      = pymeth->fMethodInfo->fFlags;
 
  592      Int_t nMethods = methods.size();
 
  594      TCallContext ctxt = { 0 };
 
  602      if ( nMethods == 1 ) {
 
  603         PyObject* result = methods[0]->Call( pymeth->fSelf, args, kwds, &ctxt );
 
  604         return HandleReturn( pymeth, oldSelf, result );
 
  608      Long_t sighash = HashSignature( args );
 
  611      MethodProxy::DispatchMap_t::iterator 
m = dispatchMap.find( sighash );
 
  612      if ( 
m != dispatchMap.end() ) {
 
  614         PyObject* result = methods[ index ]->Call( pymeth->fSelf, args, kwds, &ctxt );
 
  615         result = HandleReturn( pymeth, oldSelf, result );
 
  621         ResetCallState( pymeth->fSelf, oldSelf, 
kTRUE );
 
  626         std::stable_sort( methods.begin(), methods.end(), PriorityCmp );
 
  630      std::vector< PyError_t > errors;
 
  631      for ( 
Int_t i = 0; i < nMethods; ++i ) {
 
  632         PyObject* result = methods[i]->Call( pymeth->fSelf, args, kwds, &ctxt );
 
  636            dispatchMap[ sighash ] = i;
 
  637            std::for_each( errors.begin(), errors.end(), PyError_t::Clear );
 
  638            return HandleReturn( pymeth, oldSelf, result );
 
  642         if ( ! PyErr_Occurred() ) {
 
  644            PyObject* sig = methods[i]->GetPrototype();
 
  645            PyErr_Format( PyExc_SystemError, 
"%s =>\n    %s",
 
  650         PyErr_Fetch( &
e.fType, &
e.fValue, &
e.fTrace );
 
  651         errors.push_back( 
e );
 
  652         ResetCallState( pymeth->fSelf, oldSelf, 
kFALSE );
 
  657         "none of the %d overloaded methods succeeded. Full details:", nMethods );
 
  662      for ( std::vector< PyError_t >::iterator 
e = errors.begin(); 
e != errors.end(); ++
e ) {
 
  663         if ( 
e->fType != PyExc_NotImplementedError ) {
 
  664            if ( ! exc_type ) exc_type = 
e->fType;
 
  665            else if ( exc_type != 
e->fType ) exc_type = PyExc_TypeError;
 
  671      Py_DECREF( separator );
 
  672      std::for_each( errors.begin(), errors.end(), PyError_t::Clear );
 
  675      PyErr_SetObject( exc_type ? exc_type : PyExc_TypeError, value );
 
  683   MethodProxy* mp_descrget( MethodProxy* pymeth, ObjectProxy* pyobj, 
PyObject* )
 
  688      *pymeth->fMethodInfo->fRefCount += 1;
 
  689      newPyMeth->fMethodInfo = pymeth->fMethodInfo;
 
  693      newPyMeth->fSelf = pyobj;
 
  704      pymeth->fSelf = NULL;
 
  705      pymeth->fMethodInfo = 
new MethodProxy::MethodInfo_t;
 
  707      PyObject_GC_Track( pymeth );
 
  714   void mp_dealloc( MethodProxy* pymeth )
 
  716      PyObject_GC_UnTrack( pymeth );
 
  718      if ( ! IsPseudoFunc( pymeth ) )
 
  719         Py_CLEAR( pymeth->fSelf );
 
  720      pymeth->fSelf = NULL;
 
  722      if ( --(*pymeth->fMethodInfo->fRefCount) <= 0 ) {
 
  723         delete pymeth->fMethodInfo;
 
  726      PyObject_GC_Del( pymeth );
 
  734   Long_t mp_hash( MethodProxy* pymeth )
 
  736      return _Py_HashPointer( pymeth->fMethodInfo );
 
  742   int mp_traverse( MethodProxy* pymeth, visitproc visit, 
void* args )
 
  744      if ( pymeth->fSelf && ! IsPseudoFunc( pymeth ) )
 
  745         return visit( (
PyObject*)pymeth->fSelf, args );
 
  753   int mp_clear( MethodProxy* pymeth )
 
  755      if ( ! IsPseudoFunc( pymeth ) )
 
  756         Py_CLEAR( pymeth->fSelf );
 
  757      pymeth->fSelf = NULL;
 
  765   PyObject* mp_richcompare( MethodProxy* self, MethodProxy* other, 
int op )
 
  771      if ( ( 
Py_TYPE(self) == 
Py_TYPE(other) && self->fMethodInfo == other->fMethodInfo ) && \
 
  772           ( ( IsPseudoFunc( self ) && IsPseudoFunc( other ) ) || self->fSelf == other->fSelf ) ) {
 
  773         Py_INCREF( Py_True );
 
  776      Py_INCREF( Py_False );
 
  786         PyErr_Format( PyExc_TypeError, 
"disp() argument 1 must be string, not %.50s",
 
  787                       sigarg == Py_None ? 
"None" : 
Py_TYPE(sigarg)->tp_name );
 
  794      for ( 
Int_t i = 0; i < (
Int_t)methods.size(); ++i ) {
 
  796         PyObject* sig2 = methods[ i ]->GetSignature();
 
  797         if ( PyObject_RichCompareBool( sig1, sig2, Py_EQ ) ) {
 
  800            MethodProxy* newmeth = mp_new( NULL, NULL, NULL );
 
  802            newmeth->Set( pymeth->fMethodInfo->fName, vec );
 
  804            if ( pymeth->fSelf && ! IsPseudoFunc( pymeth ) ) {
 
  805               Py_INCREF( pymeth->fSelf );
 
  806               newmeth->fSelf = pymeth->fSelf;
 
  824      TPythonCallback* cb = 
new TPythonCallback(new_overload);
 
  825      pymeth->AddMethod( cb );
 
  826      Py_INCREF( Py_None );
 
  830   PyMethodDef mp_methods[] = {
 
  831      { (
char*)
"disp",             (PyCFunction)mp_disp, METH_O, (
char*)
"select overload for dispatch" },
 
  832      { (
char*)
"__add_overload__", (PyCFunction)mp_add_overload, METH_O, (
char*)
"add a new overload" },
 
  833      { (
char*)NULL, NULL, 0, NULL }
 
  840#if !defined(_MSC_VER) 
  841#pragma GCC diagnostic push 
  842#pragma GCC diagnostic ignored "-Wdeprecated-declarations" 
  848   (
char*)
"ROOT.MethodProxy", 
 
  851   (destructor)mp_dealloc,    
 
  862   (ternaryfunc)mp_call,      
 
  867   Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,      
 
  868   (
char*)
"PyROOT method proxy (internal)",      
 
  869   (traverseproc)mp_traverse, 
 
  871   (richcmpfunc)mp_richcompare,                  
 
  880   (descrgetfunc)mp_descrget, 
 
  893#
if PY_VERSION_HEX >= 0x02030000
 
  896#
if PY_VERSION_HEX >= 0x02060000
 
  899#
if PY_VERSION_HEX >= 0x03040000
 
  902#
if PY_VERSION_HEX >= 0x03080000
 
  904#
if PY_VERSION_HEX < 0x03090000
 
  910#if !defined(_MSC_VER) 
  911#pragma GCC diagnostic pop 
  927   if ( 
name == 
"__init__" )
 
  932        name.find( 
"Clone" ) != std::string::npos )
 
  941   fMethodInfo->fMethods.push_back( 
pc );
 
  949   fMethodInfo->fMethods.insert( fMethodInfo->fMethods.end(),
 
  959   for ( Methods_t::iterator it = fMethods.begin(); it != fMethods.end(); ++it ) {
 
#define PyROOT_PyUnicode_Append
 
#define PyROOT_PyUnicode_Check
 
#define PyROOT_PyUnicode_AsString
 
#define PyROOT_PyUnicode_AppendAndDel
 
#define PyROOT_PyUnicode_FromString
 
#define PyROOT_PyUnicode_FromFormat
 
#define PyVarObject_HEAD_INIT(type, size)
 
void Set(const std::string &name, std::vector< PyCallable * > &methods)
 
std::vector< PyCallable * > Methods_t
 
void AddMethod(PyCallable *pc)
Fill in the data of a freshly created method proxy.
 
MethodInfo_t * fMethodInfo
 
size_t SizeOf(TCppType_t klass)
 
R__EXTERN PyObject * gLifeLine
 
R__EXTERN PyObject * gROOTns
 
PyObject * GetScopeProxy(Cppyy::TCppScope_t)
Retrieve scope proxy from the known ones.
 
Bool_t IsCreator(UInt_t flags)
 
Bool_t IsConstructor(UInt_t flags)
 
Bool_t ObjectProxy_Check(T *object)
 
PyTypeObject MethodProxy_Type
 
Bool_t IsSorted(UInt_t flags)
 
static constexpr double pc
 
~MethodInfo_t()
Destructor (this object is reference counted).
 
MethodProxy::Methods_t fMethods
 
static ECallFlags sMemoryPolicy