[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 11:22:13 CEST 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