Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does PyArg_ParseTupleAndKeywords work?

I've been trying to learn how to write C-extensions for Python and want to be sure I understand how PyArg_ParseTupleAndKeywords works.

I believe that the first argument is a PyObject pointer that points to an array of the arguments being passed into the C-extension function in the order they were passed. The second argument is a list of keywords that were passed, the positions at which they were passed and, very likely, some sort of indicator flag telling at which position the keywords begin and position becomes irrelevant.

PyArg_ParseTupleAndKeywords then uses its list of keywords (4th argument) to map between arguments specified with a keyword and both the format string (3rd argument) and addresses of C variables (5th & + arguments) to which the appropriate values should be copied.

Is my understanding correct? When I read through the online documentation, all I see are references to "positional arguments and keyword arguments", which leave me feeling a little bit in the dark. Where is the file for the Python interpreter that handles PyArg_ParseTupleAndKeywords?

like image 614
user1245262 Avatar asked May 16 '12 20:05

user1245262


People also ask

What is PyObject?

PyObject is an object structure that you use to define object types for Python. All Python objects share a small number of fields that are defined using the PyObject structure. All other object types are extensions of this type. PyObject tells the Python interpreter to treat a pointer to an object as an object.

What is a keyword argument in Python?

Keyword arguments (or named arguments) are values that, when passed into a function, are identifiable by specific parameter names. A keyword argument is preceded by a parameter and the assignment operator, = . Keyword arguments can be likened to dictionaries in that they map a value to a keyword. A.

How do you convert an argument to a string in Python?

Python has a built-in function str() which converts the passed argument into a string format. The str() function returns a string version of an object. The object can be int , char , or a string . If the object is not passed as an argument, then it returns an empty string.


1 Answers

To emulate the following in python:

def keywords(a, b, foo=None, bar=None, baz=None):
    pass

The following will work:

static PyObject *keywords(PyObject *self, PyObject *args, PyObject *kwargs)
{
    char *a;
    char *b;
    char *foo = NULL;
    char *bar = NULL;
    char *baz = NULL;

    // Note how "a" and "b" are included in this
    // even though they aren't supposed to be in kwargs like in python
    static char *kwlist[] = {"a", "b", "foo", "bar", "baz", NULL};

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ss|sss", kwlist, 
                                     &a, &b, &foo, &bar, &baz)) 
    {
        return NULL;
    }

    printf("a is %s\n", a);
    printf("b is %s\n", b);
    printf("foo is %s\n", foo);
    printf("bar is %s\n", bar);
    printf("baz is %s\n", baz);

    Py_RETURN_NONE;
}

// ...

static PyMethodDef SpamMethods[] = 
{
    // ...
    {"keywords", (PyCFunction) keywords, METH_VARARGS | METH_KEYWORDS, "practice kwargs"},
    {NULL, NULL, 0, NULL}
    // ...
}

And to use it:

from spam import keywords

keywords()         # Fails, require a and b
keywords('a')      # fails, requires b
keywords('a', 'b')
keywords('a', 'b', foo='foo', bar='bar', baz='baz') 
keywords('a', 'b','foo', 'bar', 'baz')
keywords(a='a', b='b', foo='foo', bar='bar', baz='baz')
like image 93
Matthew Moisen Avatar answered Oct 10 '22 05:10

Matthew Moisen