[Python-Dev] Garbage collecting closures

Tim Peters tim_one@email.msn.com
Sat, 12 Apr 2003 04:56:42 -0400

[Paul Prescod]
> Just FYI, even if it wouldn't have leaked forever,

It wouldn't.

> it caused me serious pain because it kept a reference to a COM object.
> The process wouldn't die until the object died and all of my usual
> techniques for breaking circular references were of no avail. I even
> tried nasty hacks like globals.clear() and self.__dict__.clear(). But
> there was no circular reference to be broken.

There is, but I don't think you *can* break it.  Stick

    print foo, foo.func_closure[1]

inside your bar() function, after foo's definition.  foo.func_closure is a
2-tuple here, and you'll see that its last element is a cell, which in turn
points back to foo.  That's the cycle.  Since func_closure is a readonly
attr, and tuples and cells are immutable, there shouldn't be anything you
can do to break this cycle.

Calling gc.collect() will reclaim it, provided it has become unreachable.

Hiding critical resources in closures is a Bad Idea, of course -- that's why
nobody has used Scheme since 1993 <wink>.