Is there any way to use pythonappend with SWIG's new builtin feature? Is there any way to use pythonappend with SWIG's new builtin feature? python python

Is there any way to use pythonappend with SWIG's new builtin feature?


I agree with you that using typemap gets a little messy, but it is the right way to accomplish this task. You are also right that the SWIG documentation does not directly say that %pythonappend is incompatible with -builtin, but it is strongly implied: %pythonappend adds to the Python proxy class, and the Python proxy class does not exist at all in conjunction with the -builtin flag.

Before, what you were doing was having SWIG convert the C++ std::vector objects into Python tuples, and then passing those tuples back down to numpy - where they were converted again.

What you really want to do is convert them once, at the C level.

Here's some code which will turn all std::vector<int> objects into NumPy integer arrays:

%{#include "numpy/arrayobject.h"%}%init %{    import_array();%}%typemap(out) std::vector<int> {    npy_intp result_size = $1.size();    npy_intp dims[1] = { result_size };    PyArrayObject* npy_arr = (PyArrayObject*)PyArray_SimpleNew(1, dims, NPY_INT);    int* dat = (int*) PyArray_DATA(npy_arr);    for (size_t i = 0; i < result_size; ++i) {        dat[i] = $1[i];    }    $result = PyArray_Return(npy_arr);}

This uses the C-level numpy functions to construct and return an array. In order, it:

  • Ensures NumPy's arrayobject.h file is included in the C++ output file
  • Causes import_array to be called when the Python module is loaded (otherwise, all NumPy methods will segfault)
  • Maps any returns of std::vector<int> into NumPy arrays with a typemap

This code should be placed before you %import the headers which contain the functions returning std::vector<int>. Other than that restriction, it's entirely self-contained, so it shouldn't add too much subjective "mess" to your codebase.

If you need other vector types, you can just change the NPY_INT and all the int* and int bits, otherwise duplicating the function above.