[Cython] __dealloc__ called even if __cinit__ failed

Stefan Behnel stefan_ml at behnel.de
Thu Oct 8 17:35:06 CEST 2015


Jeroen Demeyer schrieb am 05.10.2015 um 16:04:
> I'm not entirely sure if this is a feature or bug...
> 
> I noticed that, if a __cinit__ call raises an exception on an object, that
> __dealloc__ on that same object is still called.
> 
> The problem is that __cinit__ is supposed to set up the C-level attributes
> for that object. If this somehow fails, then the object isn't in a
> consistent state yet, so it makes no sense to call __dealloc__ on it.
> 
> Do you consider this a Cython bug or should I manually protect my code
> against this?

In addition to what was already answered, note that __cinit__() is called
*after* the CPython instantiation of the class, so the object is fully
alive at that point. If the error happens in the middle of an inheritance
chain, then the object is created and the upper __cinit__() methods have
run, but the lower ones have not and will not be. Since the overall process
failed, the object is collected immediately and the __dealloc__() methods
are called, all of them, one after the other.

Calling no __dealloc__() methods at all would be wrong here and easily
leads to resource leaks. But trying to decide in such a case which
__dealloc__() methods to call and which not would just make things overly
complex and potentially difficult to understand. Calling all of them and
letting users guard against uninitialised fields is much simpler, also
handles other error cases at the user level and is generally more
predictable for all sides.

Stefan



More information about the cython-devel mailing list