[Cython] Bug in NULL handling introduced 0.14.1-1

Chris Colbert 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.
>>>
>>> --
>>> Greg
>>>
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/cython-devel/attachments/20110213/4d033a8b/attachment.html>


More information about the cython-devel mailing list