Using SWIG typemaps to generate overloaded Python wrapper

335 views Asked by At

I am using SWIG to generate Python bindings for a library (lets call it Spam) that is written in C++. The library internally defines its own Vector datatype, defined in the Spam::Vector class.

Consider the following functions to be wrapped:

void ham(Spam::Vector &vec_in, Spam::Vector &vec_out);
void eggs(Spam::Vector &vec_in, double arg2, double result);

I would like to be able to call these functions using Python lists AND NumPy arrays as inputs (instead of having to create a Spam::Vector object in Python and then populate it using the associated C++ methods - it is very unpythonic).

How would I go about writing the SWIG typemap to achieve this? Also, is there a way to incorporate/leverage numpy.i for this purpose?

1

There are 1 answers

0
Flexo On BEST ANSWER

The right way to do this is with a custom typemap. Precisely what this will look like depends a lot on the type Spam::Vector itself. In general though you can do this with something like:

%typemap(in) {
  // Maybe you'd rather check for iterable here, with this check after numpy?
  if (PyList_Check($input)) {
    $1 = ... // Code to iterate over a list and prepare a Spam::Vector
  }
  else if (PyType_IsSubtype($input->ob_type, NumpyType)) {
    $1 = ... // Code to convert from numpy input
  }
  else {
    // code to raise an error
  }
}

There are various hacks that might be possible in other more specific circumstances, but this is the general solution.