[Python-Dev] Design question: call __del__ only after successful __init__?

Guido van Rossum guido@python.org
Thu, 02 Mar 2000 10:32:32 -0500

I was looking at the code that invokes __del__, with the intent to
implement a feature from Java: in Java, a finalizer is only called
once per object, even if calling it makes the object live longer.

To implement this, we need a flag in each instance that means "__del__
was called".  I opened the creation code for instances, looking for
the right place to set the flag.  I then realized that it might be
smart, now that we have this flag anyway, to set it to "true" during
initialization.  There are a number of exits from the initialization
where the object is created but not fully initialized, where the new
object is DECREF'ed and NULL is returned.  When such an exit is taken,
__del__ is called on an incompletely initialized object!  Example:

	>>> class C:
	  def __del__(self): print "deleting", self

	>>> x = C(1)
 !-->   deleting <__main__.C instance at 1686d8>
	Traceback (innermost last):
	  File "<stdin>", line 1, in ?
	TypeError: this constructor takes no arguments

Now I have a choice to make.  If the class has an __init__, should I
clear the flag only after __init__ succeeds?  This means that if
__init__ raises an exception, __del__ is never called.  This is an
incompatibility.  It's possible that someone has written code that
relies on __del__ being called even when __init__ fails halfway, and
then their code would break.

But it is just as likely that calling __del__ on a partially
uninitialized object is a bad mistake, and I am doing all these cases
a favor by not calling __del__ when __init__ failed!

Any opinions?  If nobody speaks up, I'll make the change.

--Guido van Rossum (home page: http://www.python.org/~guido/)