[Python-Dev] Design question: call __del__ for cyclical garbage?

Greg Stein gstein@lyra.org
Sat, 4 Mar 2000 00:43:45 -0800 (PST)

On Fri, 3 Mar 2000, Tim Peters wrote:
> [a nice implementation sketch, of what seems an overly elaborate scheme,
>  if you believe cycles with finalizers are rare in intelligently designed
>  code)
> ]

Nah. Quite simple to code up, but a bit longer to explain in English :-)

The hardest part is finding the cycles, but Guido already posted a long
explanation about that. Once that spits out the doubly-linked list of
objects, then you're set.

1) scan the list calling tp_clean(CARE_CHECK), shoving "care needed"
   objects to a second list
2) scan the care-needed list calling tp_clean(CARE_EXEC). if TRUE is
   returned, then the object was cleaned and moves to the "no care" list.
3) assert len(care-needed list) == 0
4) scan the no-care list calling tp_clean(EXEC)
5) (questionable) assert len(no-care list) == 0

The background makes it longer. The short description of the algorithm is
easy. Step (1) could probably be merged right into one of the scans in the
GC algorithm (e.g. during the placement into the "these are cyclical
garbage" list)

> Provided Guido stays interested in this, he'll make his own fun.  I'm just
> inviting him to move in a sane direction <0.9 wink>.

hehe... Agreed.

> One caution:
> > ...
> > If the careful-cleaning algorithm hits the end of the careful set of
> > objects and the set is non-empty, then throw an exception:
> > GCImpossibleError.
> Since gc "can happen at any time", this is very severe (c.f. Guido's
> objection to making resurrection illegal).

GCImpossibleError would simply be a subclass of MemoryError. Makes sense
to me, and definitely allows for its "spontaneity."

> Hand a trash cycle back to the
> programmer instead, via callback or request or whatever, and it's all
> explicit without more cruft in the implementation.  It's alive again when
> they get it back, and they can do anything they want with it (including
> resurrecting it, or dropping it again, or breaking cycles -- anything).  I'd
> focus on the cycles themselves, not on the types of objects involved.  I'm
> not pretending to address the "order of finalization at shutdown" question,
> though (although I'd agree they're deeply related:  how do you follow a
> topological sort when there *isn't* one?  well, you don't, because you
> can't).

I disagree. I don't think a Python-level function is going to have a very
good idea of what to do. IMO, this kind of semantics belong down in the
interpreter with a specific, documented algorithm. Throwing it out to
Python won't help -- that function will still have to use a "standard
pattern" for getting the cyclical objects to toss themselves. I think that
standard pattern should be a language definition. Without a standard
pattern, then you're saying the application will know what to do, but that
is kind of weird -- what happens when an unexpected cycle arrives?


Greg Stein, http://www.lyra.org/