Work in progress

This section discusses Python specific wrapper details.



type fields


Argument for Py_BuildValue. Defaults to {cxx_var}. This field can be used to turn the argument into an expression such as (int) {cxx_var} or {cxx_var}{cxx_member}c_str() PY_build_format is used as the format:

Py_BuildValue("{PY_build_format}", {PY_build_arg});


‘format unit’ for Py_BuildValue. If None, use value of PY_format. Defaults to None


‘format unit’ for PyArg_Parse and Py_BuildValue. Defaults to O


Variable name of PyTypeObject instance. Defaults to None.


Typedef name of PyObject instance. Defaults to None.


Expression to create object. ex. PyInt_FromLong({rv}) Defaults to None.


Expression to get value from an object. ex. PyInt_AsLong({py_var}) Defaults to None.


Create an Python object for the type. Includes the index of the destructor function. Used with structs/classes that are created by functions and must be wrapped. object = converter(address, idtor). Defaults to None.


PyBuild - object = converter(address). Defaults to None.


PyArg_Parse - status = converter(object, address). Defaults to None.


The type returned by PY_get function. Defaults to None which implies it is the same as the typemap. i.e. PyInt_AsLong returns a long.

Defined for complex types because PyComplex_AsCComplex returns type Py_complex. See also pytype_to_pyctor and pytype_to_cxx.


Expression to use with PY_ctor. Defaults to None which indicates no additional processing of the argument is required. Only needs to be defined when py_ctype is defined.

With complex types, it is used to extract the real and imaginary parts from Py_complex (defined with py_ctype) with creal({ctor_expr}), cimag({ctor_expr}). ctor_expr is the expression used with Py_ctor.


Expression to convert py_ctype into a C++ value. Only needs to be defined when py_ctype is defined.

Used with complex to convert Py_complex (defined with py_ctype) to C using {work_var}.real + {work_var}.imag * I or C++ with std::complex(\tcvalue.real, cvalue.imag).


Statements to convert cxx_var to py_ctype/ Only needs to be defined when py_ctype is defined.

cxx_to_pytype: |
    {ctype_var}.real = creal({cxx_var});
    {ctype_var}.imag = cimag({cxx_var});


Name of PyArray_Descr variable which describe type. Used with structs. Defaults to None.


NumPy type number. ex. NPY_INT Defaults to None.


The template for a function is:

static char {PY_name_impl}__doc__[] = "{PY_doc_string}";

static PyObject *'
    {PY_PyObject} *{PY_param_self},
    PyObject *{PY_param_args},
    PyObject *{PY_param_kwds})

    // {parse_format}  {parse_args}
    if (!PyArg_ParseTupleAndKeywords(
        {PY_param_args}, {PY_param_kwds}, "{PyArg_format}",
        SH_kw_list, {PyArg_vargs})) {
        return NULL;

    // result pre_call

    // Create C from Python objects
    // Create C++ from C
    {               create scope before fail
      {pre_call}    pre_call declares variables for arguments

      call  {arg_call}

      per argument
        // Create Python object from C++
        {ctor}    {post_call}

        {PyObject} *  {py_var} Py_BuildValue("{Py_format}", {vargs});


The template for a setter is:

static PyObject *{PY_getter}(
    {PY_PyObject} *{PY_param_self},
    void *SHROUD_UNUSED(closure)) {

The template for a getter is:

static int {PY_setter}("
    {PY_PyObject} *{PY_param_self},
    PyObject *{py_var},
    void *SHROUD_UNUSED(closure)) {
    return 0;

Fields listed in the order they generate code. C variables are created before the call to Py_ParseArgs. C++ variables are then created in post_parse and pre_call. For example, creating a std::string from a char *.


Functions which return a struct/class instance (such as std::vector) need to allocate a local variable which will be used to store the result. The Python object will maintain a pointer to the instance until it is deleted.




Blank delimited list of helper functions required for the wrapper. The name may contain format strings and will be expand before it is used. ex. to_PyList_{cxx_type}. The function associated with the helper will be named hnamefunc0, hnamefunc1, … for each helper listed.


If True, add NumPy headers and initialize in the module.


Update format dictionary to override generated values. Each field will be evaluated before assigment.

ctor_expr - Expression passed to Typemap.PY_ctor PyInt_FromLong({ctor_expr}). Useful to add dereferencing if necessary. PyInt_FromLong is from typemap.PY_ctor.



By default a local variable will be declared the same type as the argument to the function.

For some cases, this will not be correct. This field will be used to replace the default declaration.


In some cases the declaration is correct but need to be initialized. For example, setting a pointer.

Assign a blank list will not add any declarations. This is used when only an output std::string or std::vector is created after parsing arguments.

This variables is used with PyArg_ParseTupleAndKeywords.

The argument will be non-const to allow it to be assigned later.

    "{c_const}char {c_var}[{charlen}];  // intent(out)",


Code needed to declare local variable. Often used to define variables of type PyObject *.


Set when a C++ variable is created by post_parse. scalar

Used to set format fields cxx_member


Works together with parse_args to describe how to parse PyObject in PyArg_ParseTupleAndKeywords. parse_format is used in the format arguments and parse_args is append to the call as a vararg.

int PyArg_ParseTupleAndKeywords(PyObject *args, PyObject *kw,
    const char *format, char *keywords[], ...)

The simplest use is to pass the object directly through so that it can be operated on by post_parse or pre_call to convert the object into a C/C++ variable. For example, convert a PyObject into an int *.

    "PyObject * {pytmp_var};",

The format field pytmp_var is created by Shroud, but must be declared if it is used.

It can also be used to provide a converter function which converts the object:

parse_args=["{hnamefunc0}", "&{py_var}"],

From the Python manual: Note that any Python object references which are provided to the caller (of PyArg_Parse) are borrowed references; do not decrement their reference count!


A list of wrapper variables that are passed to PyArg_ParseTupleAndKeywords. Used with parse_format.


Set to scalar or pointer depending on the declaration in post_declare post_parse or pre_call.


Declaration of C++ variables after calling PyArg_ParseTupleAndKeywords. Usually involves object constructors such as std::string or std::vector. Or for extracting struct and class pointers out of a PyObject.

These declarations should not include goto fail. This allows them to be created without a “jump to label ‘fail’ crosses initialization of” error.

“It is possible to transfer into a block, but not in a way that bypasses declarations with initialization. A program that jumps from a point where a local variable with automatic storage duration is not in scope to a point where it is in scope is ill-formed unless the variable has POD type (3.9) and is declared without an initializer.”


Statements to execute after the call to PyArg_ParseTupleAndKeywords. Used to convert C values into C++ values:

{var} = PyObject_IsTrue({var_obj});

Will not be added for class constructor objects. since there is no need to build return values.

Allow intent(in) arguments to be processed. For example, process PyObject into PyArrayObject.


Location to allocate memory for output variables. All intent(in) variables have been processed by post_parse so their lengths are known.


List of arguments to pass to function.


Convert result and intent(out) into PyObject. Set object_created to True if a PyObject is created.


Code to remove any intermediate variables.


Code to remove allocated memory and created objects.


If True, one of the other blocks such as post_parse, pre_call, and post_call contain a call to fail. If any statements block sets goto_fail, then the fail block will be inserted into the code/


Set to True when a PyObject is created by post_call. This prevents Py_BuildValue from converting it into an Object. For example, when a pointer is converted into a PyCapsule or when NumPy is used to create an object.

Predefined Types


An int argument is converted to Python with the typemap:

type: int
    PY_format: i
    PY_ctor: PyInt_FromLong({c_deref}{c_var})
    PY_get: PyInt_AsLong({py_var})
    PYN_typenum: NPY_INT


When a function returns a pointer to a POD type several Python interfaces are possible. When a function returns an int * the simplest result is to return a PyCapsule. This is just the raw pointer returned by C++. It’s also the least useful to the caller since it cannot be used directly. The more useful option is to assume that the result is a pointer to a scalar. In this case a NumPy scalar can be returned or a Python object such as int or float.

If the C++ library function can also provide the length of the pointer, then its possible to return a NumPy array. If owner(library) is set, the memory will never be released. If owner(caller) is set, the the memory will be released when the object is deleted.

The argument int *result+intent(OUT)+dimension(3) will create a NumPy array, then pass the pointer to the data to the C function which will presumably fill the contents. The NumPy array will be returned as part of the function result. The dimension attribute must specify a length.

Class Types

An extension type is created for each C++ class:

typedef struct {
    {namespace_scope}{cxx_class} * {PY_obj};
} {PY_PyObject};

Extension types

Additional type information can be provided in the YAML file to generate place holders for extension type methods:

- name: ExClass2
  cxx_header: ExClass2.hpp
    type: [dealloc, print, compare, getattr, setattr,
           getattro, setattro,
           repr, hash, call, str,
           init, alloc, new, free, del]