[Cython] Bug in NULL handling introduced 0.14.1-1
sccolbert at gmail.com
Sun Feb 13 21:49:04 CET 2011
changing the include definition to:
cdef extern from "Python.h":
int PyObject_GenericSetAttr(PyObject*, PyObject*, PyObject*) except -1
Seems to solve the problem, with the inconvenience of needing to explicitly
cast to <PyObject*> before calling it. However, the objects are no longer
incref'd before calling, so this may or not be an issue.
On Sun, Feb 13, 2011 at 3:39 PM, Chris Colbert <sccolbert at gmail.com> wrote:
> I should mention, that these PyObject_Generic* functions are being used
> from with __getattribute__, __setattr__, and __delattr__ methods. I should
> have added that context in the begining.
> On Sun, Feb 13, 2011 at 3:37 PM, Chris Colbert <sccolbert at gmail.com>wrote:
>> The problem with delattr (and thus PyObject_DelAttr) arises when you
>> define a __delattr__ method on your class. There is not easy way to then
>> call back into the "normal" python delattr semantics, except by doing
>> object.__delattr__ (which is not optimized by Cython).
>> Futher, calling PyObject_GenericSetattr(obj, name, NULL) appears to be the
>> proper use, given that it properly follows the descriptor chain and will
>> call __delete__ if obj.name is a descriptor.
>> I would argue that there should be at least some way to pass a NULL
>> pointer in Cython where a PyObject* is expected.
>> On Sun, Feb 13, 2011 at 3:31 PM, Greg Ewing <greg.ewing at canterbury.ac.nz>wrote:
>>> Chris Colbert wrote:
>>>> I have cython file which is using PyObject_GenericSetAttr
>>>> Now in my script I am using that function to generically delete an
>>>> attribute by passing a NULL as the last value (this is proper way to trigger
>>>> a generic delattr in the Python c-api)
>>> I would have thought the proper way to do that was to use
>>> PyObject_DelAttr, which Pyrex exposes as delattr().
>>> I don't think PyObject_GenericSetAttr is even meant to be
>>> called directly -- it's intended for filling the tp_setattr
>>> slot of type objects.
>>> This causes a segfault because the NULL is getting increfed via
>>>> Py_INCREF instead of Py_XINCREF.
>>> I would recommend against trying to "fix" this. You got
>>> away with it before because you happened to be passing the
>>> NULL value directly to a function which is expecting it.
>>> But casting NULL to an object reference is not something
>>> that should be encouraged, because in any other context it
>>> would quickly lead to disaster.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the cython-devel