From b421b8c19105d08b97122b7c84eec37ad83c6de4 Mon Sep 17 00:00:00 2001 From: Fred Drake Date: Fri, 26 Oct 2001 16:21:32 +0000 Subject: Added two new functions to conveniently call functions/methods from C. PyObject_CallFunctionObArgs() and PyObject_CallMethodObArgs() have the advantage that no format strings need to be parsed. The CallMethod variant also avoids creating a new string object in order to retrieve a method from an object as well. --- Include/abstract.h | 28 ++++++++++++++++---- Objects/abstract.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+), 5 deletions(-) diff --git a/Include/abstract.h b/Include/abstract.h index 351149d..0d44f6d 100644 --- a/Include/abstract.h +++ b/Include/abstract.h @@ -299,7 +299,6 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/ PyObject *args, PyObject *kw); /* - Call a callable Python object, callable_object, with arguments and keywords arguments. The 'args' argument can not be NULL, but the 'kw' argument can be NULL. @@ -310,7 +309,6 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/ PyObject *args); /* - Call a callable Python object, callable_object, with arguments given by the tuple, args. If no arguments are needed, then args may be NULL. Returns the result of the @@ -343,11 +341,31 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/ arguments are provided. Returns the result of the call on success, or NULL on failure. This is the equivalent of the Python expression: o.method(args). + */ + - Note that Special method names, such as "__add__", - "__getitem__", and so on are not supported. The specific - abstract-object routines for these must be used. + DL_IMPORT(PyObject *) PyObject_CallFunctionObArgs(PyObject *callable, + ...); + /* + Call a callable Python object, callable_object, with a + variable number of C arguments. The C arguments are provided + as PyObject * values; 'n' specifies the number of arguments + present. Returns the result of the call on success, or NULL + on failure. This is the equivalent of the Python expression: + apply(o,args). + */ + + + DL_IMPORT(PyObject *) PyObject_CallMethodObArgs(PyObject *o, + PyObject *m, ...); + + /* + Call the method named m of object o with a variable number of + C arguments. The C arguments are provided as PyObject * values; + 'n' specifies the number of arguments present. Returns the + result of the call on success, or NULL on failure. This is the + equivalent of the Python expression: o.method(args). */ diff --git a/Objects/abstract.c b/Objects/abstract.c index 6b9201b..003c9a3 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -1758,6 +1758,82 @@ PyObject_CallMethod(PyObject *o, char *name, char *format, ...) } +static PyObject * +obargs_mktuple(va_list va) +{ + int i, n = 0; + va_list countva; + PyObject *result, *tmp; + +#ifdef VA_LIST_IS_ARRAY + memcpy(countva, va, sizeof(va_list)); +#else + countva = va; +#endif + + while (((PyObject *)va_arg(countva, PyObject *)) != NULL) + ++n; + result = PyTuple_New(n); + if (result != NULL && n > 0) { + for (i = 0; i < n; ++i) { + tmp = (PyObject *)va_arg(va, PyObject *); + PyTuple_SET_ITEM(result, i, tmp); + Py_INCREF(tmp); + } + } + return result; +} + +PyObject * +PyObject_CallMethodObArgs(PyObject *callable, PyObject *name, ...) +{ + PyObject *args, *tmp; + va_list vargs; + + if (callable == NULL || name == NULL) + return null_error(); + + callable = PyObject_GetAttr(callable, name); + if (callable == NULL) + return NULL; + + /* count the args */ + va_start(vargs, name); + args = obargs_mktuple(vargs); + va_end(vargs); + if (args == NULL) { + Py_DECREF(callable); + return NULL; + } + tmp = PyObject_Call(callable, args, NULL); + Py_DECREF(args); + Py_DECREF(callable); + + return tmp; +} + +PyObject * +PyObject_CallFunctionObArgs(PyObject *callable, ...) +{ + PyObject *args, *tmp; + va_list vargs; + + if (callable == NULL) + return null_error(); + + /* count the args */ + va_start(vargs, callable); + args = obargs_mktuple(vargs); + va_end(vargs); + if (args == NULL) + return NULL; + tmp = PyObject_Call(callable, args, NULL); + Py_DECREF(args); + + return tmp; +} + + /* isinstance(), issubclass() */ static PyObject * -- cgit v0.12