[Numpy-discussion] subclassing array in c
Christoph Gohlke
cgohlke@uci....
Wed Mar 7 20:01:14 CST 2012
FWIW, this crashes on Windows with numpy 1.6.1 but not numpy 1.7-git
debug build.
Christoph Gohlke
On 3/7/2012 5:36 PM, Val Kalatsky wrote:
>
> Tried it on my Ubuntu 10.10 box, no problem:
>
> 1) Saved as spampub.c
> 2) Compiled with (setup.py attached): python setup.py build_ext -i
> 3) Tested from ipython:
> In [1]: import spampub
> In [2]: ua=spampub.UnitArray([0,1,2,3.0],'liter')
> In [3]: ua
> Out[3]: UnitArray([ 0., 1., 2., 3.])
> In [4]: ua.unit
> Out[4]: 'liter'
>
>
> On Wed, Mar 7, 2012 at 7:15 PM, Val Kalatsky <kalatsky@gmail.com
> <mailto:kalatsky@gmail.com>> wrote:
>
>
> 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 <mailto: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 <mailto:NumPy-Discussion@scipy.org>
> http://mail.scipy.org/mailman/listinfo/numpy-discussion
>
>
>
>
>
> _______________________________________________
> NumPy-Discussion mailing list
> NumPy-Discussion@scipy.org
> http://mail.scipy.org/mailman/listinfo/numpy-discussion
More information about the NumPy-Discussion
mailing list