7

Take a canonical Python function defined like:

def foo(*args, **kwargs):
  print("args:", len(args))
  for i in args:
    print(i)

  print("kwargs:", len(kwargs))
  for k in kwargs:
    print(k, kwargs[k])

Calling this function from Python might look like:

some_list = ['one', 'two', 'three']
some_kwords = { "name1" : "alice", "name2" : "bob", "name3" : "carol" }

foo(*some_list, **some_kwords)

Does the Python C API provide some way to call this function from C space? How can the above three lines be converted to C equivalent?

Note that in a similar question, using boost::python, C++ calls into this keyword argument function with almost the same syntax as from Python, which is quite a trick!

Community
  • 1
  • 1
greatwolf
  • 20,287
  • 13
  • 71
  • 105

1 Answers1

5

To call a function with arbitrary positional and keyword arguments in Python/C, equivalent to the function(*args, **kwds) syntax, use PyObject_Call:

/* error checking omitted for brevity */
PyObject *some_list = PyObject_BuildValue("(sss)", "one", "two", "three");
PyObject *some_kwords = PyObject_BuildValue("{s:s,s:s,s:s}",
                          "name1", "alice", "name2", "bob", "name3", "carol");
PyObject *ret = PyObject_Call(foo, some_list, some_kwords);
Py_DECREF(some_list);
Py_DECREF(some_kwords);
user4815162342
  • 141,790
  • 18
  • 296
  • 355