"GvR" == Guido van Rossum <guido@python.org> writes:
GvR> Now I have a choice to make. If the class has an __init__, GvR> should I clear the flag only after __init__ succeeds? This GvR> means that if __init__ raises an exception, __del__ is never GvR> called. This is an incompatibility. It's possible that GvR> someone has written code that relies on __del__ being called GvR> even when __init__ fails halfway, and then their code would GvR> break.
[Barry]
It reminds me of the separation between object allocation and initialization in ObjC.
Is that good or bad?
GvR> But it is just as likely that calling __del__ on a partially GvR> uninitialized object is a bad mistake, and I am doing all GvR> these cases a favor by not calling __del__ when __init__ GvR> failed!
GvR> Any opinions? If nobody speaks up, I'll make the change.
I think you should set the flag right before you call __init__(), i.e. after (nearly all) the C level initialization has occurred. Here's why: your "favor" can easily be accomplished by Python constructs in the __init__():
class MyBogo: def __init__(self): self.get_delified = 0 do_sumtin_exceptional() self.get_delified = 1
def __del__(self): if self.get_delified: ah_sweet_release()
But the other behavior (call __del__ even when __init__ fails) can also easily be accomplished in Python: class C: def __init__(self): try: ...stuff that may fail... except: self.__del__() raise def __del__(self): ...cleanup... I believe that in almost all cases the programmer would be happier if __del__ wasn't called when their __init__ fails. This makes it easier to write a __del__ that can assume that all the object's fields have been properly initialized. In my code, typically when __init__ fails, this is a symptom of a really bad bug (e.g. I just renamed one of __init__'s arguments and forgot to fix all references), and I don't care much about cleanup behavior. --Guido van Rossum (home page: http://www.python.org/~guido/)