Swig typemaps cheatsheet

The documentation of SWIG is pretty extensive, but there isn’t a single point that document all available macros / substitution mechanisms available while writing a typemap. It’s a nightmare to find what you’re looking for when you’re not already really familiar with it, so to save myself and maybe a few others from early hair loss, here is a quick list of some useful substitutions I found.

Assuming I’m writing an out typemap for a template<class T> class Handle;

$1The local copy of the C/C++ object
$resultThe output PyObject to return to Python
$1_typeThe type of the C/C++ object (Handle<T>)
$1_descriptor The SWIG type descriptor corresponding to Handle<T>
$&1_descriptor The SWIG type descriptor corresponding to Handle<T> *

The case I was trying to cover when I almost became bald is the following: I have a templated Handle class (as you’ve probably already guessed) that’s used to encapsulate a heap allocated data. Some API functions / methods bound in Python return such handles in place of pointers, but I wanted the those to return None in Python instead of returning an invalid handle.

So I basically needed a typemap that checked the validity of my handle, and if invalid returned None, otherwise returned the usual SWIG object. Here is the simplified typemap:

%typemap(out) Handle {
    if ($1.valid() == false) {
        $result = Py_None;
    } else {
        // this fucking $&1_descriptor is at the origin of this post...
        $result = SWIG_NewPointerObj(new $type(std::move($1)), $&1_descriptor, SWIG_POINTER_OWN);
    }
}