How to parse userdefined types (or types from an existing non-standard library) using PyArg_ParseTuple?
 
    
    - 1,048,767
- 296
- 4,058
- 3,343
 
    
    - 121
- 6
2 Answers
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.
 
    
    - 4,641
- 2
- 27
- 34
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.
 
    
    - 1,048,767
- 296
- 4,058
- 3,343