[Python-3000] PEP: Eliminate __del__

Giovanni Bajo rasky at develer.com
Thu May 3 09:25:44 CEST 2007

On 01/05/2007 18.09, Phillip J. Eby wrote:

>> The alternative is to code the automatic finalization steps using
>> weakref callbacks.  For those used to using __del__, it takes a little
>> while to learn the idiom but essentially the technique is hold a proxy
>> or ref with a callback to a boundmethod for finalization:
>>     self.resource = resource = CreateResource()
>>     self.callbacks.append(proxy(resource, resource.closedown))
>> In this manner, all of the object's resources can be freed automatically
>> when the object is collected.  Note, that the callbacks only bind
>> the resource object and not client object, so the client object
>> can already have been collected and the teardown code can be run
>> without risk of resurrecting the client (with a possibly invalid state).
> I'm a bit confused about the above.  My understanding is that in order for 
> a weakref's callback to be invoked, the weakref itself *must still be 
> live*.  That means that if 'self' in your example above is collected, then 
> the weakref no longer exists, so the closedown won't be called.

Yes, but as far as I understand it, the GC does special care to ensure that 
the callback of a weakref that is *not* part of a cyclic trash being collected 
is always called. See this comment in gcmodule.c:

	 * OTOH, if wr isn't part of CT, we should invoke the callback:  the
	 * weakref outlived the trash.  Note that since wr isn't CT in this
	 * case, its callback can't be CT either -- wr acted as an external
	 * root to this generation, and therefore its callback did too.  So
	 * nothing in CT is reachable from the callback either, so it's hard
	 * to imagine how calling it later could create a problem for us.  wr
	 * is moved to wrcb_to_call in this case.

I might be wrong about the inners of GC, but I have used the weakref idiom 
many times and it always appeared to be working.

> In principle I'm in favor of ditching __del__, as long as there's actually 
> a viable technique for doing so.  My own experience has been that setting 
> up a simple mechanism to replace it (and that actually works) is really 
> difficult, because you have to find some place for the weakref itself to 
> live, which usually means a global dictionary or something of that 
> sort.

Others suggested that such a framework could be prepared, but I have not seen 
one yet.

   It would be nice if the gc or weakref modules grew a facility to
> make it easier to register finalization callbacks, and could optionally 
> check whether you were registering a callback that referenced the thing you 
> were tying the callback's life to.

That'd be absolutely great! OTOH, the GC could possibly re-verify such 
assertion every time it kicks in (when a special debug flag is activated).
Giovanni Bajo
Develer S.r.l.

More information about the Python-3000 mailing list