I have an iterable PyObject
that I need to pass as the list of arguments to a Python callable, ala
xs = [1,2,5,7]
some_function(*xs)
However, PyObject_CallObject
only allows tuples to be passed as the arguments' container.
I'm not sure, though, what is the best way to create a new tuple containing the elements of an iterable. Here's a tentative code:
PyObject* unpack_call(PyObject* callable, PyObject* args) {
PyObject* tuple;
if (PyTuple_Check(args)) {
tuple = args;
} else {
PyObject* iter = PyObject_GetIter(args);
if (!iter) return NULL;
tuple = PyTuple_New(0);
for (Py_ssize_t pos=0; ; ++pos) {
PyObject* arg = PyIter_Next(iter);
if (!arg) break;
PyTuple_SetItem(tuple,pos,arg);
}
}
return PyObject_CallObject(callable,tuple);
}
I'm not sure if I need to grow the size of the tuple myself or not. What's confusing me is the sentence in the documentation saying:
The tuple will always grow or shrink at the end.
I'm also not sure if I need to increment or decrement reference counts for any of these objects.