True *args and **kwargs in Python C extension

Viewed 2270

I am developing Python 3 C extension.

Can I get the equivalent or arbitrary positional or keyword arguments?

For instance, in Python, I can write:

def fun(name, parent, *args, **kwargs):
    # do something with name and parent
    # do something with args and kwargs
    pass

But I cannot find of a simple equivalent in C. While we can perfectly write functions with PyObject* args and PyObject* kwargs, I cannot easily "parse out" name and parent from whichever (args/kwargs) it came.

Take:

static PyObject* myFunction(PyObject* self, PyObject* args, PyObject* kwargs) {
    char* kwds[] = {"parent", "name", NULL};
    PyObject* name = NULL;
    PyObject* parent = NULL;
    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO", kwds, &parent, &name)) {
        goto errorParseTupleAndKeywords;
    }
    /* Do something with name and parent */
    /* parent and name maybe have appeared either in args or kwargs */
    /* But I don't have any extra positional (*args) or keyword (**kwargs) here */    
}

A "manual" approach that I could think of looks roughly like:

static PyObject* myFunction(PyObject* self, PyObject* args, PyObject* kwargs) {
    PyObject* name = NULL;
    PyObject* parent = NULL;
    int inKwargs = 0;
    // Pretend to do something with parent
    if (PyDict_GetItemString(kwargs, "parent")) {
        inKwargs++;
        PyDict_DelItemString(kwargs, "parent");
    }
    // Pretend to do something with name
    if (PyDict_GetItemString(kwargs, "name")) {
        inKwargs++;
        PyDict_DelItemString(kwargs, "name");
    }
    // Not sure if -1 works here
    PyObject* newArgs = PyTuple_GetSlice(args, inKwargs, -1); // this is *args
    // the remaining kwargs can be used as **kwargs
}
1 Answers
Related