def make_manual_returnVal(buffer, output_list):

    buffer.write('\n  int i = 0;')
    buffer.write('\n  PyObject *t = NULL;')
    buffer.write(
        '\n  PyObject *returnVal = PyTuple_New(%d);' % len(output_list))

    count = 0;
    for count in range(len(output_list)):
        output = output_list[count]

        if output.allocate_memory:
            buffer.write('\n  t = PyTuple_New(%s);' % output_list[0].name)
            buffer.write(
                '\n  for(i = 0; i < %s; ++ i) {' % output_list[0].name
            )
            buffer.write(
                '\n    PyTuple_SET_ITEM(t, i, Py_BuildValue("%s", %s[i]));' % \
                (output.py_string, output.name)
            )
            buffer.write('\n  }')
            buffer.write('\n  PyTuple_SET_ITEM(returnVal, %d, t);' % count)
        else:
            buffer.write(
                '\n  PyTuple_SET_ITEM(returnVal, %d, Py_BuildValue("%s", %s));' % \
                (count, output.py_string, output.name)
            )

    buffer.write('\n  return returnVal;');
This returnVal function is used when the output dimensions are dynamic.
dataset/ETHPy150Open rca/PySPICE/mkwrapper.py/make_manual_returnVal