[Python-Dev] Bizarre new test failure

Guido van Rossum guido@python.org
Sun, 09 Jun 2002 16:02:20 -0400


[Guido]
> > I tried the simplest possible fix, which was to visit self->ob_type in
> > the new-style instance tp_traverse handler (subtype_traverse() in
> > typeobject.c).  But this caused assertions to fail all over the place.
> > It turns out that when the collector decides to break a cycle like
> > this, it calls the tp_clear handler for each object in the cycle, and
> > then the subsequent deletion of the instance references the type in
> > ways that have been made invalid by the clearing of the type.  So this
> > was a dead end.

[Martin]
> I'd like to question this statement. It ought to be possible, IMO, to
> dealloc an instance whose type has been cleared.
> 
> The problem appears to be in the tp_clear. The task of tp_clear is to
> clear all references that may participate in cycles (*not* to clear
> all references per se). Now, if type_clear would clear tp_dict,
> tp_subclasses, and et->slots, but leave alone tp_base, tp_bases, and
> tp_mro, the type would still be "good enough" for subtype_dealloc, no?

Alas, I don't think so.

When tp_dict is cleared, this can remove the __del__ method before it
can be called (it is called by the instance's tp_dealloc).  But
tp_dict has to be cleared, because it can participate in cycles
(e.g. you could do A.A = A).

tp_mro participates in a cycle too: it is a tuple whose first element
is the type itself.  Tuples are immutable, so the tp_clear for tuples
doesn't do anything.  So type_clear is our only hope to break this
cycle.

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