[Python-Dev] Calling Methods from Pythons C API with Keywords

Hrvoje Nikšić hrvoje.niksic at avl.com
Wed Jun 20 09:34:49 CEST 2007


On Wed, 2007-06-20 at 00:21 +1000, Campbell Barton wrote:
> I want to add my own call's before and after PyLists standard functions
> but have a proplem with functons that use keywords and have no API
> equivalent.
> For example, I cant use the API's PyList_Sort because that dosnt support
> keywords like...
> 
> ls.sort(key=lambda a: a.foo))
> 
> And the Problem with PyObject_CallMethod is that it dosnt accept keywords.

Note that you can always simply call PyObject_Call on the bound method
object retrieved using PyObject_GetAttrString.  The hardest part is
usually constructing the keywords dictionary, a job best left to
Py_BuildValue and friends.  When I need that kind of thing in more than
one place, I end up with a utility function like this one:

/* Equivalent to PyObject_CallMethod but accepts keyword args.  The
   format... arguments should produce a dictionary that will be passed
   as keyword arguments to obj.method.

   Usage example:
     PyObject *res = call_method(lst, "sort", "{s:O}", "key", keyfun));
*/

PyObject *
call_method(PyObject *obj, const char *methname, char *format, ...)
{
  va_list va;
  PyObject *meth = NULL, *args = NULL, *kwds = NULL, *ret = NULL;

  args = PyTuple_New(0);
  if (!args)
    goto out;
  meth = PyObject_GetAttrString(obj, methname);
  if (!meth)
    goto out;

  va_start(va, format);
  kwds = Py_VaBuildValue(format, va);
  va_end(va);
  if (!kwds)
    goto out;

  ret = PyObject_Call(meth, args, kwds);
 out:
  Py_XDECREF(meth);
  Py_XDECREF(args);
  Py_XDECREF(kwds);
  return ret;
}

It would be nice for the Python C API to support a more convenient way
of calling objects and methods with keyword arguments.




More information about the Python-Dev mailing list