[c-api]Transmutation of an extension object into a read-only buffer adding an integer in-place.

Giacomo Alzetta giacomo.alzetta at gmail.com
Fri Aug 10 05:25:36 EDT 2012


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.



More information about the Python-list mailing list