[Python-Dev] Bizarre new test failure
Tim Peters
tim_one@email.msn.com
Fri, 7 Jun 2002 03:49:27 -0400
[Neil Schemenauer]
> It's easy to reproduce. First, disable the GC. Next, run:
>
> regrtest.py test_descr test_gc
Sorry, thinking is cheating.
> My wild guess is that some tp_clear method is not doing it's job. I'll
> take a closer look tomorrow if someone hasn't figured it out by then.
> Must sleep. Too much CS.
Ya, Canadian sausage always does me in too. I'll attach a self-contained
(in the sense that you can run it directly by itself, without regrtest.py)
test program. Guido might have some idea what does <wink>. For me, it
prints:
collected 3
collected 51
collected 9
collected 0
and, at the end, collected 1
and it's not a coincidence that 9+1 == 10 (the failing value seen when
running the test suite). It suggests one easy way to fix test_gc <wink>.
> I wonder if some new cyclic garbage structure needs two gc.collect()
> passes in order to break it up.
If there isn't a bug, this case takes 3(!) passes.
from test_support import vereq
def supers():
class A(object):
def meth(self, a):
return "A(%r)" % a
class B(A):
def __init__(self):
self.__super = super(B, self)
def meth(self, a):
return "B(%r)" % a + self.__super.meth(a)
class C(A):
def meth(self, a):
return "C(%r)" % a + self.__super.meth(a)
C._C__super = super(C)
class D(C, B):
def meth(self, a):
return "D(%r)" % a + super(D, self).meth(a)
class mysuper(super):
def __init__(self, *args):
return super(mysuper, self).__init__(*args)
class E(D):
def meth(self, a):
return "E(%r)" % a + mysuper(E, self).meth(a)
class F(E):
def meth(self, a):
s = self.__super
return "F(%r)[%s]" % (a, s.__class__.__name__) + s.meth(a)
F._F__super = mysuper(F)
vereq(F().meth(6), "F(6)[mysuper]E(6)D(6)C(6)B(6)A(6)")
import gc
gc.disable()
L = []
L.append(L)
supers()
while 1:
n = gc.collect()
print "collected", n
if n == 0:
break
del L
n = gc.collect()
print
print "and, at the end, collected", n