Il giorno venerdì 10 agosto 2012 11:22:13 UTC+2, Hans Mulder ha scritto: > On 10/08/12 10:20:00, Giacomo Alzetta wrote: > > > I'm trying to implement a c-extension which defines a new > > class(ModPolynomial on the python side, ModPoly on the C-side). > > > At the moment I'm writing the in-place addition, but I get a *really* > > strange behaviour. > > > > > > Here's the code for the in-place addition: > > > > > > #define ModPoly_Check(v) (PyObject_TypeCheck(v, &ModPolyType)) > > > [...] > > > static PyObject * > > > ModPoly_InPlaceAdd(PyObject *self, PyObject *other) > > > { > > > > > > if (!ModPoly_Check(self)) { > > > // This should never occur for in-place addition, am I correct? > > > if (!ModPoly_Check(other)) { > > > PyErr_SetString(PyExc_TypeError, "Neither argument is a > > ModPolynomial."); > > > return NULL; > > > } > > > return ModPoly_InPlaceAdd(other, self); > > > } else { > > > if (!PyInt_Check(other) && !PyLong_Check(other)) { > > > Py_INCREF(Py_NotImplemented); > > > return Py_NotImplemented; > > > } > > > } > > > > > > ModPoly *Tself = (ModPoly *)self; > > > PyObject *tmp, *tmp2; > > > tmp = PyNumber_Add(Tself->ob_item[0], other); > > > tmp2 = PyNumber_Remainder(tmp, Tself->n_modulus); > > > > > > Py_DECREF(tmp); > > > tmp = Tself->ob_item[0]; > > > Tself->ob_item[0] = tmp2; > > > Py_DECREF(tmp); > > > > > > printf("%d\n", (int)ModPoly_Check(self)); > > > return self; > > > > > > } > > > > I have no experience writing extensions in C, but as I see it, > > you're returning a new reference to self, so you'd need: > > > > Py_INCREF(self); > > > > If you don't, then a Py_DECREF inside the assignment operator > > causes your polynomial to be garbage collected. Its heap slot > > is later used for the unrelated buffer object you're seeing. > > > > Hope this helps, > > > > -- HansM
Yes, you're right. I didn't thought the combined operator would do a Py_DECREF if the iadd operation was implemented, but it obviosuly makes sense. -- http://mail.python.org/mailman/listinfo/python-list