[Numpy-discussion] subclassing array in c

Val Kalatsky kalatsky@gmail....
Wed Mar 7 19:15:15 CST 2012


Seeing the backtrace would be helpful.
Can you do whatever leads to the segfault
from python run from gdb?
Val

On Wed, Mar 7, 2012 at 7:04 PM, Christoph Gohle
<christoph.gohle@mpq.mpg.de>wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Hi,
>
> I have been struggeling for quite some time now. Desperate as I am, now I
> need help.
>
> I was trying to subclass ndarrays in a c extension (see code below) and do
> constantly get segfaults. I have been checking my INCREF and DECREF stuff
> up and down but can't find the error. Probably I got something completely
> wrong... anybody able to help?
>
> Thanks,
> Christoph
> - -----------------
> #include <Python.h>
> #include <structmember.h>
>
> #include <numpy/arrayobject.h>
>
> static PyObject *SpamError;
>
> typedef struct {
>  PyArrayObject base;
>  PyDictObject* unit;
> } UnitArrayObject;
>
> PyTypeObject unitArrayObjectType;
>
> static int
> checkunit(PyObject *unit1, PyObject *unit2) {
>  return PyObject_Compare(unit1, unit2);
> }
>
> static PyObject *
> unitArray_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs) {
>        PyObject *data = NULL,
>                         *unit = NULL;
>  PyArray_Descr* dtype = NULL;
>  PyObject *res = NULL, *tmp = NULL;
>
>        if (!PyArg_ParseTuple(args, "OO|O&", &data, &unit,
> PyArray_DescrConverter, &dtype)) {
>                Py_XDECREF(dtype);
>                return NULL;
>        }
>
>  res = PyArray_FromAny(data, dtype, 0, 0, NPY_ENSURECOPY, NULL);
>        if (res == NULL) {
>                Py_XDECREF(dtype);
>    //TODO: raise exception?
>                return NULL;
>        }
>
>        if (PyObject_IsInstance(data, (PyObject*)cls)) {
>                if (unit!=NULL &&
> !checkunit((PyObject*)((UnitArrayObject*)data)->unit,unit)) {
>                        Py_XDECREF(res);
>                        //TODO: raise exception
>                        return NULL;
>                }
>        } else {
>                if (PyObject_IsTrue(unit)) {
>      tmp = res;
>                        res = PyArray_View((PyArrayObject*)res, NULL,
> &unitArrayObjectType);
>      if (tmp!=res) {
>        Py_XDECREF(tmp);
>      }
>      ((UnitArrayObject*)res)->unit = (PyDictObject*)unit;
>      Py_INCREF(unit);
>      if (unit!=NULL) {
>      }
>                }
>        }
>        return res;
> }
>
> static PyObject*
> unitArray__array_finalize__(PyObject* new, PyObject* args) {
>        PyObject *attr = NULL, *tmp = NULL;
>  PyObject *parent = NULL;
>
>  if (!PyArg_ParseTuple(args, "O", &parent)) {
>    return NULL;
>  }
>   if (parent!=NULL) {
>     attr = PyObject_GetAttrString(parent, "unit");
>     if (attr == NULL) {
>        //parent has no 'unit' so we make a new empty one
>       attr = PyDict_New();
>       PyErr_Clear();
>     }
>   }
>  tmp = (PyObject*)((UnitArrayObject*)new)->unit;
>    ((UnitArrayObject*)new)->unit = (PyDictObject*)attr;
>
>  Py_INCREF(Py_None);
>  return Py_None;
> }
>
> static PyObject*
> unitArray__array_wrap__(PyObject *self, PyObject *args) {
>        PyObject *array = NULL, *context = NULL;
>
>        if (!PyArg_ParseTuple(args, "OO", array, context)) {
>                //TODO: raise exception
>                return NULL;
>        }
>
>        printf("%s",PyString_AsString(PyObject_Str(context)));
>
>  Py_INCREF(array);
>  return array;
> }
>
>
> static PyMethodDef unitArrayMethods[] = {
>  {"__array_finalize__", unitArray__array_finalize__, METH_VARARGS, "array
> finalize method"},
>  {"__array_wrap__", unitArray__array_wrap__, METH_VARARGS, "array wrap
> method"},
>  {NULL, NULL, 0, NULL}
> };
>
> static PyMemberDef unitArrayMembers[] = {
>  {"unit", T_OBJECT, offsetof(UnitArrayObject, unit),  0, "dictionary
> containing unit info."},
>  {NULL, 0, 0, 0, NULL}
> };
>
> PyTypeObject unitArrayObjectType = {
>        PyObject_HEAD_INIT(NULL)
>        0,                              /* ob_size        */
>        "spam.UnitArray",               /* tp_name        */
>        sizeof(UnitArrayObject),                /* tp_basicsize   */
>        0,                              /* tp_itemsize    */
>        0,                              /* 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,             /* tp_flags       */
>        "A numpy array with units",     /* tp_doc         */
>  0,        /* traverseproc */
>  0,        /* tp_clear*/
>  0,        /* tp_richcompare */
>  0,        /* tp_weaklistoffset */
>  0,        /* tp_iter */
>  0,        /* tp_iternext */
>  unitArrayMethods,        /* tp_methods */
>  unitArrayMembers,        /* tp_members */
>  0,        /* tp_getset */
>  0,        /* tp_base*/
>  0,        /* tp_dict */
>  0,        /* tp_descr_get*/
>  0,        /* tp_descr_set */
>  0,        /* tp_dictoffset */
>  0,        /* tp_init */
>  0,        /* tp_alloc */
>  unitArray_new /* tp_new */
> };
>
>
> static PyMethodDef SpamMethods[] = {
>    {NULL, NULL, 0, NULL}        /* Sentinel */
> };
>
> PyObject *unitArray = NULL;
> PyMODINIT_FUNC
> initspampub(void)
> {
>  import_array();
>
>  PyObject *m;
>
>  Py_INCREF(&PyArray_Type);
>  unitArrayObjectType.tp_base = &PyArray_Type;
>
>  if (PyType_Ready(&unitArrayObjectType) < 0)
>    return;
>
>
>  m = Py_InitModule3("spampub", SpamMethods, "some tests and a array type
> with units.");
>  if (m == NULL)
>    return;
>
>  SpamError = PyErr_NewException("spampub.error", NULL, NULL);
>  Py_INCREF(SpamError);
>  PyModule_AddObject(m, "error", SpamError);
>  Py_INCREF(&unitArrayObjectType);
>  PyModule_AddObject(m, "UnitArray", (PyObject *)&unitArrayObjectType);
>  (void) Py_InitModule("spampub", SpamMethods);
>
> }
>
>
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG/MacGPG2 v2.0.14 (Darwin)
>
> iEYEARECAAYFAk9YBbkACgkQLYu25rCEIzsExQCggHg0e0ibYP3bEsAE0Ce8Rbm3
> qOcAoKwuTuE4BDZgrqNpwISgMS6uSMnO
> =Qtek
> -----END PGP SIGNATURE-----
> _______________________________________________
> NumPy-Discussion mailing list
> NumPy-Discussion@scipy.org
> http://mail.scipy.org/mailman/listinfo/numpy-discussion
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.scipy.org/pipermail/numpy-discussion/attachments/20120307/4a0bb2ab/attachment-0001.html 


More information about the NumPy-Discussion mailing list