[Python-Dev] Bizarre new test failure

Jeremy Hylton jeremy@zope.com
Fri, 7 Jun 2002 08:41:20 -0400


>>>>> "TP" == Tim Peters <tim.one@comcast.net> writes:

  TP> For some reason, the cell nags me.  Perhaps because of your
  TP> "must be inside function scope" comment, and that cells are
  TP> poorly understood by me <wink>.

I can explain the cells, at least.

def main():
    # must be inside function scope
    class A(object):
        def __init__(self):
            self.__super = super(A, self)

    A()

In the example, the value bound to A is stored in a cell, because it
is a free variable in __init__().  There are two references to the
cell after the class statement is executed.  One is the frame for
main().  The other is the func_closure for __init__().

The second reference creates a cycle.  The cycle is:

class A refers to
function __init__ refers to
cell for A refers to
class A

That's it for what I understand.

It looks like the example code creates two cycles, and one cycle
refers to the other.  The first cycle is the one involving the A
instance and the super instance variable.  That cycle has a reference
to class A.

When the garbage collector runs, it determines the first cycle is
garbage.  It doesn't determine the second cycle is garbage because it
has an external reference from the first cycle.

I presume that the garbage collector can't collect both cycles in one
pass without re-running the update & subtract refs phase after
deleting all the garbage.  During the first refs pass, the second
cycle wasn't detected.  The second cycle is only collectable after the
first cycle has been collected.

Jeremy