1.8 Keyword Parsing with PyArg_ParseTupleAndKeywords()
Keywords: ext

#
1.8 Keyword Parsing with `PyArg_ParseTupleAndKeywords()`

The `PyArg_ParseTupleAndKeywords()` function is declared as follows:

      int PyArg_ParseTupleAndKeywords(PyObject *arg, PyObject *kwdict,
                                      char *format, char **kwlist, ...);

The arg and format parameters are identical to those of the `PyArg_ParseTuple()` function. The kwdict parameter is the dictionary of keywords received as the third parameter from the Python runtime. The kwlist parameter is a `NULL`-terminated list of strings which identify the parameters; the names are matched with the type information from format from left to right.

Note: Nested tuples cannot be parsed when using keyword arguments! Keyword parameters passed in which are not present in the kwlist will cause `TypeError` to be raised.

Here is an example module which uses keywords, based on an example by Geoff Philbrick (philbrick@hks.com):

      #include <stdio.h>
      #include "Python.h"

      static PyObject *
      keywdarg_parrot(self, args, keywds)
          PyObject *self;
          PyObject *args;
          PyObject *keywds;
      {
          int voltage;
          char *state = "a stiff";
          char *action = "voom";
          char *type = "Norwegian Blue";

          static char *kwlist[] = {"voltage", "state", "action", "type", NULL};

          if (!PyArg_ParseTupleAndKeywords(args, keywds, "i|sss", kwlist,
                                           &voltage, &state, &action, &type))
              return NULL;

          printf("-- This parrot wouldn't %s if you put %i Volts through it.\n",
                 action, voltage);
          printf("-- Lovely plumage, the %s -- It's %s!\n", type, state);

          Py_INCREF(Py_None);

          return Py_None;
      }

      static PyMethodDef keywdarg_methods[] = {
          /* The cast of the function is necessary since PyCFunction values
           * only take two PyObject* parameters, and keywdarg_parrot() takes
           * three.
           */
          {"parrot", (PyCFunction)keywdarg_parrot, METH_VARARGS|METH_KEYWORDS},
          {NULL,  NULL}   /* sentinel */
      };

      void
      initkeywdarg()
      {
        /* Create the module and add the functions */
        Py_InitModule("keywdarg", keywdarg_methods);
      }