Implementing nb_inplace_add results in returning a read-only buffer object

隐身守侯 提交于 2020-01-05 12:13:50

问题


I'm writing an implementation of the in-place add operation. But, for some reason, I sometimes get a read-only buffer as result(while I'm adding a custom extension class and an integer...).

The relevant code is:

static PyObject *
ModPoly_InPlaceAdd(PyObject *self, PyObject *other)
{

    if (!ModPoly_Check(self)) {
        //Since it's in-place addition the control flow should never
        // enter here(I suppose)
        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);
    return (PyObject *)Tself;

}

If instead of returning (PyObject*)Tself(or simply "self"), I raise an exception, the original object gets update correctly[checked using some printf]. If I use the Py_RETURN_NONE macro, it correctly turns the ModPoly into None (in the python side).

What am I doing wrong? I'm returning a pointer to a ModPoly object, how can this become a buffer? And I don't see any operation on those pointers.

example usage:

>>> from algebra import polynomials
>>> pol = polynomials.ModPolynomial(3,17)
>>> pol += 5
>>> pol
<read-only buffer ptr 0xf31420, size 4 at 0xe6faf0>

I've tried change the return line into:

printf("%d\n", (int)ModPoly_Check(self));
return self;

and it prints 1 when adding in-place (meaning that the value returned is of type ModPolynomial...)


回答1:


According to the documentation, the inplace add operation for an object returns a new reference.

By returning self directly without calling Py_INCREF on it, your object will be freed while it is still referenced. If some other object is allocated the same piece of memory, those references would now give you the new object.



来源:https://stackoverflow.com/questions/11897597/implementing-nb-inplace-add-results-in-returning-a-read-only-buffer-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!