6

How to parse userdefined types (or types from an existing non-standard library) using PyArg_ParseTuple?

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
dhanesh sr
  • 121
  • 6

2 Answers2

5

Instead of using the plain O format, as Martijn suggested, I normally prefer using the O& format. It allows you to pass a function that will be called to convert any PyObject* to an arbitrary C (double) pointer. Here is some example usage, in which I'm converting a passed value to a pointer to my own object type:

/** 
 * This method should return 0 if it does not work or 1 in case it does
 * PyArg_*() functions will handle the rest from there or let your program
 * continue in case things are fine.
 */
int MyConverter(PyObject* o, MyOwnType** mine) {
  //write the converter here.
}

Then, at the point you need to parse your object:

/**
 * Simple example
 */
static PyObject* py_do_something(PyObject*, PyObject* args, PyObject* kwds) {

    /* Parses input arguments in a single shot */
    static char* kwlist[] = {"o", 0};

    MyOwnType* obj = 0; ///< if things go OK, obj will be there after the next call

    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&", kwlist, &MyConverter, &obj))
      return 0; ///< we have failed, let Python check exceptions.

    /* if you get to this point, your converter worked, just use */
    /* your newly allocated object and free it, when done. */

}

The advantage of this approach is that you can encapsulate your MyConverter on a C-API and then re-use it in other functions for the the same job.

André Anjos
  • 4,641
  • 2
  • 27
  • 34
3

Custom python classes can be parsed using the O format:

O (object) [PyObject *]
Store a Python object (without any conversion) in a C object pointer. The C program thus receives the actual object that was passed. The object’s reference count is not increased. The pointer stored is not NULL.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343