Python object extension which gets a list in constructor never passes the creation step (SIGSEV), why?
Question: I've been fighting for a lot of time with an error and I've run short of ideas
on what's happening and why it doesn't work.

First of all, I'm trying to create a new object type for Python through a C
extension. This object is created using a list, numpy array etc... But I
cannot even make this part work.

The actual minimal code that fails is:

    
    
        #include <python2.7/Python.h>
        #include <python2.7/structmember.h>
        #include <numpy/arrayobject.h>
        #include "../python/NumpyHelperFuncs.h"
        #include <cmath>
        #include <algorithm>
        #include <iostream>
        using namespace std;
    
        typedef struct {
            PyObject_HEAD
        } CondensedMatrix;
    
        static void condensedMatrix_dealloc(CondensedMatrix* self){
            self->ob_type->tp_free((PyObject*)self);
        }
    
        static PyObject* condensedMatrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds){
            CondensedMatrix *self;
            self = (CondensedMatrix*) type->tp_alloc(type, 0);
            return (PyObject *) self;
        }
    
        static int condensedMatrix_init(CondensedMatrix *self, PyObject *args, PyObject *kwds){
            PyObject* input;
            PyArrayObject* rmsd_numpy_array;
            cout<<"Minimum class creation"<<flush<<endl;
    
            if (! PyArg_ParseTuple(args, "O",&input)){
                PyErr_SetString(PyExc_RuntimeError, "Error parsing parameters.");
                return -1;
            }
            rmsd_numpy_array = (PyArrayObject *) PyArray_ContiguousFromObject(input, PyArray_FLOAT, 1, 1);
            Py_DECREF(rmsd_numpy_array);
            return 0;
        }
    
        static PyMemberDef condensedMatrix_members[] = {
            {NULL}  /* Sentinel */
        };
    
    
        static PyMethodDef condensedMatrix_methods[] = {
            {NULL}  /* Sentinel */
        };
    
        static PyTypeObject CondensedMatrixType = {
            PyObject_HEAD_INIT(NULL)
            0,                                              /*ob_size*/
            "condensedMatrix.CondensedMatrixType",          /*tp_name*/
            sizeof(CondensedMatrix),    /*tp_basicsize*/
            0,                         /*tp_itemsize*/
            (destructor)condensedMatrix_dealloc, /*tp_dealloc*/
            0,                         /*tp_print*/
            0,                         /*tp_getattr*/
            0,                         /*tp_setattr*/
            0,                         /*tp_compare*/
            0,                         /*tp_repr*/
            0,                         /*tp_as_number*/
            0,                         /*tp_as_sequence*/
            0,                         /*tp_as_mapping*/
            0,                         /*tp_hash */
            0,                         /*tp_call*/
            0,                         /*tp_str*/
            0,                         /*tp_getattro*/
            0,                         /*tp_setattro*/
            0,                         /*tp_as_buffer*/
            Py_TPFLAGS_DEFAULT| Py_TPFLAGS_BASETYPE ,                       /*tp_flags*/
            "Condensed matrix as in pdist",         /* tp_doc */
            0,                     /* tp_traverse */
            0,                     /* tp_clear */
            0,                     /* tp_richcompare */
            0,                     /* tp_weaklistoffset */
            0,                         /* tp_iter */
            0,                         /* tp_iternext */
            condensedMatrix_methods,   /* tp_methods */
            condensedMatrix_members,   /* tp_members */
            0,                         /* tp_getset */
            0,                         /* tp_base */
            0,                         /* tp_dict */
            0,                         /* tp_descr_get */
            0,                         /* tp_descr_set */
            0,                         /* tp_dictoffset */
            (initproc)condensedMatrix_init, /* tp_init */
            0,                              /* tp_alloc */
            condensedMatrix_new,                /* tp_new */
        };
    
        #ifndef PyMODINIT_FUNC  /* declarations for DLL import/export */
        #define PyMODINIT_FUNC void
        #endif
    
        PyMODINIT_FUNC initcondensedMatrix(void){
            PyObject* module;
    
            if (PyType_Ready(&CondensedMatrixType) < 0)
                return;
    
            module = Py_InitModule3("condensedMatrix", NULL,"Fast Access Condensed Matrix");
            if (module == NULL)
                  return;
    
            Py_INCREF(&CondensedMatrixType);
            PyModule_AddObject(module, "CondensedMatrix", (PyObject*) &CondensedMatrixType);
        }
    

This code has been written following the tips (and copy/pasting):
[http://docs.python.org/extending/newtypes.html](http://docs.python.org/extending/newtypes.html#id2)

I've tested the Noddy code and it works, but if I add a fourth parameter to
get a list, it also exits with a sigsev.

I compile the code above with:

    
    
    gcc -pthread -fno-strict-aliasing -fmessage-length=0 -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector -funwind-tables -fasynchronous-unwind-tables  -fPIC  -c matrix.cpp
    
    g++ -pthread -shared matrix/matrix.o -lpython2.7 -o condensedMatrix.so -fopenmp
    

And I use it with: if **name** == '**main** ': data_con = [3,4,5,6] matrix =
CondensedMatrix(data_con)

I've also read [PyArg_ParseTuple SegFaults in
CApi](http://stackoverflow.com/questions/7760658/pyarg-parsetuple-segfaults-
in-capi)

Does anyone know why it does a segfault after pyarg_parsetuple?

Ubuntu 12.04 , gcc 4.6.3 , Python 2.7.3

Thanks!


Answer: So, it looks like the error was indeed very easy to solve as the only needed
thing was a missing 'import_array();' sentence in the init function:

    
    
    PyMODINIT_FUNC initcondensedMatrix(void){
        PyObject* module;
    
        if (PyType_Ready(&CondensedMatrixType) < 0)
            return;
    
        module = Py_InitModule3("condensedMatrix", NULL,"Fast Access Condensed Matrix");
        if (module == NULL)
              return;
    
        Py_INCREF(&CondensedMatrixType);
        PyModule_AddObject(module, "CondensedMatrix", (PyObject*) &CondensedMatrixType);
        import_array();
    }
    

And that was all ...

