27 Py_XINCREF( pyclass );
30 std::vector< PyCallable* >
dummy;
67 PyObject_GC_Track( pytmpl );
74 int tpp_clear( TemplateProxy* pytmpl )
76 Py_CLEAR( pytmpl->fPyName );
77 Py_CLEAR( pytmpl->fPyClass );
78 Py_CLEAR( pytmpl->fSelf );
79 Py_CLEAR( pytmpl->fNonTemplated );
80 Py_CLEAR( pytmpl->fTemplated );
88 void tpp_dealloc( TemplateProxy* pytmpl )
90 PyObject_GC_UnTrack( pytmpl );
92 PyObject_GC_Del( pytmpl );
98 PyObject* tpp_doc( TemplateProxy* pytmpl,
void* )
101 if ( pytmpl->fNonTemplated )
102 doc = PyObject_GetAttrString( (
PyObject*)pytmpl->fNonTemplated,
"__doc__" );
103 if ( pytmpl->fTemplated ) {
104 PyObject* doc2 = PyObject_GetAttrString( (
PyObject*)pytmpl->fTemplated,
"__doc__" );
108 }
else if ( !doc && doc2 ) {
122 int tpp_traverse( TemplateProxy* pytmpl, visitproc visit,
void* arg )
124 Py_VISIT( pytmpl->fPyName );
125 Py_VISIT( pytmpl->fPyClass );
126 Py_VISIT( pytmpl->fSelf );
127 Py_VISIT( pytmpl->fNonTemplated );
128 Py_VISIT( pytmpl->fTemplated );
178 Py_DECREF( pymeth ); pymeth = 0;
185 Py_XDECREF( pymeth ); pymeth = 0;
191 PyErr_Format( PyExc_TypeError,
"template method \'%s\' with no arguments must be explicit",
200 PyObject* tpArgs = PyTuple_New( nArgs );
201 for (
Int_t i = 0; i < nArgs; ++i ) {
202 PyObject* itemi = PyTuple_GET_ITEM( args, i );
203 if ( PyType_Check( itemi ) ) isType =
kTRUE;
204#if PY_VERSION_HEX >= 0x03000000
205 else if ( ! isType && PyUnicode_Check( itemi ) ) nStrings += 1;
207 else if ( ! isType &&
PyBytes_Check( itemi ) ) nStrings += 1;
216 PyTuple_SET_ITEM( tpArgs, i, tp );
220 const char* ptrname = 0;
222 case 'b': ptrname =
"char*";
break;
223 case 'h': ptrname =
"short*";
break;
224 case 'H': ptrname =
"unsigned short*";
break;
225 case 'i': ptrname =
"int*";
break;
226 case 'I': ptrname =
"unsigned int*";
break;
227 case 'l': ptrname =
"long*";
break;
228 case 'L': ptrname =
"unsigned long*";
break;
229 case 'f': ptrname =
"float*";
break;
230 case 'd': ptrname =
"double*";
break;
231 default: ptrname =
"void*";
236 PyTuple_SET_ITEM( tpArgs, i, pyptrname );
241 PyTuple_SET_ITEM( tpArgs, i, pytc );
249 if ((isType || nStrings == nArgs) && pyname_v1) {
251 pymeth = PyObject_GetAttr( pytmpl->fSelf ? pytmpl->fSelf : pytmpl->fPyClass, pyname_v1 );
253 Py_DECREF( pyname_v1 );
254 if (PyErr_WarnEx(PyExc_FutureWarning,
255 "Instantiating a function template with parentheses ( f(type1, ..., typeN) ) "
256 "is deprecated and will not be supported in a future version of ROOT. "
257 "Instead, use square brackets: f[type1, ..., typeN]", 1) < 0) {
271 Py_DECREF( pymeth ); pymeth = 0;
273 Py_XDECREF( pyname_v1 );
280 Py_XDECREF( pymeth ); pymeth = 0;
291 if (clNameStr ==
"_global_cpp")
295 const std::string& tmplname = pytmpl->fNonTemplated->fMethodInfo->fName;
298 if ( ! isType && ! ( nStrings == nArgs ) ) {
304 Py_DECREF( pyname_v2 );
305 std::string
proto = mname.substr( 1, mname.size() - 2 );
310 Py_XDECREF( pyname_v1 );
312 pytmpl->fTemplated->AddMethod(
new TFunctionHolder( scope, cppmeth ) );
316 pytmpl->fTemplated->
AddMethod(
new TMethodHolder( scope, cppmeth ) );
322 pymeth = PyObject_GetAttrString(
323 pytmpl->fSelf ? pytmpl->fSelf : pytmpl->fPyClass, (
char*)
Cppyy::GetMethodName(cppmeth).c_str() );
341 PyObject_SetAttr( pytmpl->fPyClass, pyname_v1, (
PyObject*)pymeth );
342 if ( mname != cppmeth->GetName() )
343 PyObject_SetAttrString( pytmpl->fPyClass, (
char*)mname.c_str(), (
PyObject*)pymeth );
345 pymeth = PyObject_GetAttr( pytmpl->fSelf ? pytmpl->fSelf : pytmpl->fPyClass, pyname_v1 );
346 Py_DECREF( pyname_v1 );
347 if (PyErr_WarnEx(PyExc_FutureWarning,
348 "Instantiating a function template with parentheses ( f(type1, ..., typeN) ) "
349 "is deprecated and will not be supported in a future version of ROOT. "
350 "Instead, use square brackets: f[type1, ..., typeN]", 1) < 0) {
355 Py_DECREF( pyname_v1 );
359 PyErr_Format( PyExc_TypeError,
"can not resolve method template call for \'%s\'",
367 TemplateProxy* tpp_descrget( TemplateProxy* pytmpl,
PyObject* pyobj,
PyObject* )
372 Py_INCREF( pytmpl->fPyName );
373 newPyTmpl->fPyName = pytmpl->fPyName;
375 Py_XINCREF( pytmpl->fPyClass );
376 newPyTmpl->fPyClass = pytmpl->fPyClass;
379 Py_INCREF( pytmpl->fNonTemplated );
380 newPyTmpl->fNonTemplated = pytmpl->fNonTemplated;
383 Py_INCREF( pytmpl->fTemplated );
384 newPyTmpl->fTemplated = pytmpl->fTemplated;
388 newPyTmpl->fSelf = pyobj;
399 bool justOne = !PyTuple_CheckExact(args);
404 args = PyTuple_New(nArgs);
406 PyTuple_SET_ITEM(args, 0, item);
408 nArgs = PyTuple_GET_SIZE(args);
413 for (
int i = 0; i < nArgs; ++i) {
414 PyObject* itemi = PyTuple_GET_ITEM(args, i);
415 if (PyType_Check(itemi)) isType =
kTRUE;
416#if PY_VERSION_HEX >= 0x03000000
417 else if (! isType && PyUnicode_Check(itemi)) nStrings += 1;
425 if (justOne) Py_DECREF(args);
428 if ((isType || nStrings == nArgs) &&
pyname) {
430 PyObject* pymeth = PyObject_GetAttr(pytmpl->fSelf ? pytmpl->fSelf : pytmpl->fPyClass,
pyname);
445 if (clNameStr ==
"_global_cpp")
459 if (mname != cppmeth->GetName())
460 PyObject_SetAttrString(pytmpl->fPyClass, (
char*)mname.c_str(), (
PyObject*)pymeth);
462 pymeth = PyObject_GetAttr(pytmpl->fSelf ? pytmpl->fSelf : pytmpl->fPyClass,
pyname);
469 PyErr_Format(PyExc_TypeError,
"cannot resolve method template instantiation for \'%s\'",
476 static PyMappingMethods tpp_as_mapping = {
477 nullptr, (binaryfunc)tpp_subscript,
nullptr
480 PyGetSetDef tpp_getset[] = {
481 { (
char*)
"__doc__", (getter)tpp_doc, NULL, NULL, NULL },
482 { (
char*)NULL, NULL, NULL, NULL, NULL }
487#if !defined(_MSC_VER)
488#pragma GCC diagnostic push
489#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
495 (
char*)
"ROOT.TemplateProxy",
498 (destructor)tpp_dealloc,
509 (ternaryfunc)tpp_call,
514 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
515 (
char*)
"PyROOT template proxy (internal)",
516 (traverseproc)tpp_traverse,
527 (descrgetfunc)tpp_descrget,
540#
if PY_VERSION_HEX >= 0x02030000
543#
if PY_VERSION_HEX >= 0x02060000
546#
if PY_VERSION_HEX >= 0x03040000
549#
if PY_VERSION_HEX >= 0x03080000
551#
if PY_VERSION_HEX < 0x03090000
557#if !defined(_MSC_VER)
558#pragma GCC diagnostic pop
#define PyROOT_PyUnicode_Check
#define PyROOT_PyUnicode_AsString
#define PyROOT_PyUnicode_AppendAndDel
#define PyROOT_PyUnicode_FromString
#define PyVarObject_HEAD_INIT(type, size)
static RooMathCoreReg dummy
void AddMethod(PyCallable *pc)
Fill in the data of a freshly created method proxy.
Template proxy object to return functions and methods.
MethodProxy * fNonTemplated
void AddOverload(MethodProxy *mp)
Store overloads of this templated method.
void Set(const std::string &name, PyObject *pyclass)
Initialize the proxy for the given 'pyclass.'.
PyObject_HEAD PyObject * fSelf
void AddTemplate(PyCallable *pc)
TClass instances represent classes, structs and namespaces in the ROOT type system.
TMethod * GetMethodAny(const char *method)
Return pointer to method without looking at parameters.
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.
Each ROOT class (see TClass) has a linked list of methods.
virtual const char * GetName() const
Returns name of object.
TCppMethod_t GetMethodTemplate(TCppScope_t scope, const std::string &name, const std::string &proto)
Bool_t IsNamespace(TCppScope_t scope)
std::string GetMethodName(TCppMethod_t)
TCppScope_t GetScope(const std::string &scope_name)
Bool_t IsStaticMethod(TCppMethod_t method)
R__EXTERN PyObject * gName
R__EXTERN PyObject * gTypeCode
R__EXTERN PyObject * gCppName
PyObject * BuildTemplateName(PyObject *pyname, PyObject *tpArgs, int argoff, PyObject *args=nullptr, ArgPreference=kNone, int *pcnt=nullptr, bool inferredTypes=false)
Helper to construct the "< type, type, ... >" part of a templated name (either for a class as in Make...
MethodProxy * MethodProxy_New(const std::string &name, std::vector< PyCallable * > &methods)
Bool_t MethodProxy_Check(T *object)
PyTypeObject TemplateProxy_Type
PyTypeObject MethodProxy_Type
static constexpr double pc