[c-api]Transmutation of an extension object into a read-only buffer adding an integer in-place.
Hans Mulder
hansmu at xs4all.nl
Fri Aug 10 05:22:13 EDT 2012
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
More information about the Python-list
mailing list