How to parse only "kwargs" and skip arguments when calling PyArg_ParseTupleAndKeywords?

I am calling a function that takes a list of positional arguments followed by the keyword arguments. I want to handle args and kwargs separately. Unfortunately, unlike PyArg_ParseTuple for positional arguments, there is no equivalent PyArg_ParseKeywords for keyword arguments. I tried to prevent parsing of positional arguments by passing Py_None (also NULL) instead of args:

static PyObject* test_func(PyObject* self, PyObject* args, PyObject *kwargs)
{
    static const char *kwList[] = {"kw1", "kw2", NULL};
    const char* kw1_val = NULL;
    PyObject* kw2_val = NULL;

    if (! PyArg_ParseTupleAndKeywords(Py_None, 
                                      kwargs,
                                      "zO",
                                      const_cast<char**>(kwList),
                                      &kw1_val,
                                      &kw2_val))
    {
        return NULL;
    }
}

      

Having Py_None (or NULL) results in:

Python/getargs.c:1390: bad argument to internal function

      

If I replace Py_None with args I get the following error:

TypeError: function takes at most 2 arguments (4 given)

      

The above TypeError is raised because it unpacks 2 positional arguments and 2 keyword arguments that I passed to test_func, while there are only two variables, kw1_val and kw2_val, to get those 4 values ​​in the parse method.

Is there a way to handle the above scenario? Note that a positional argument can have any number of values.

+3


source to share


1 answer


Try passing an empty tuple instead Py_None

:



static PyObject* test_func(PyObject* self, PyObject* args, PyObject *kwargs)
{
    static const char *kwList[] = {"kw1", "kw2", NULL};
    const char* kw1_val = NULL;
    PyObject* kw2_val = NULL;

    PyObject *retvalue = NULL;
    PyObject *empty = PyTuple_New(0);

    if (empty == NULL){
        goto out;
    }

    if (! PyArg_ParseTupleAndKeywords(empty, 
                                      kwargs,
                                      "zO",
                                      const_cast<char**>(kwList),
                                      &kw1_val,
                                      &kw2_val))
    {
        goto out;
    }

    // other code here

out:
    Py_XDECREF(empty);
    return retvalue;
}

      

+1


source







All Articles