[Python-checkins] CVS: python/dist/src/Lib/test test_gc.py,1.9,1.10
Guido van Rossum
gvanrossum@users.sourceforge.net
Tue, 02 Oct 2001 14:24:59 -0700
Update of /cvsroot/python/python/dist/src/Lib/test
In directory usw-pr-cvs1:/tmp/cvs-serv30352/Lib/test
Modified Files:
test_gc.py
Log Message:
Add Garbage Collection support to new-style classes (not yet to their
instances).
Also added GC support to various auxiliary types: super, property,
descriptors, wrappers, dictproxy. (Only type objects have a tp_clear
field; the other types are.)
One change was necessary to the GC infrastructure. We have statically
allocated type objects that don't have a GC header (and can't easily
be given one) and heap-allocated type objects that do have a GC
header. Giving these different metatypes would be really ugly: I
tried, and I had to modify pickle.py, cPickle.c, copy.py, add a new
invent a new name for the new metatype and make it a built-in, change
affected tests... In short, a mess. So instead, we add a new type
slot tp_is_gc, which is a simple Boolean function that determines
whether a particular instance has GC headers or not. This slot is
only relevant for types that have the (new) GC flag bit set. If the
tp_is_gc slot is NULL (by far the most common case), all instances of
the type are deemed to have GC headers. This slot is called by the
PyObject_IS_GC() macro (which is only used twice, both times in
gcmodule.c).
I also changed the extern declarations for a bunch of GC-related
functions (_PyObject_GC_Del etc.): these always exist but objimpl.h
only declared them when WITH_CYCLE_GC was defined, but I needed to be
able to reference them without #ifdefs. (When WITH_CYCLE_GC is not
defined, they do the same as their non-GC counterparts anyway.)
Index: test_gc.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/test/test_gc.py,v
retrieving revision 1.9
retrieving revision 1.10
diff -C2 -d -r1.9 -r1.10
*** test_gc.py 2001/10/02 19:49:47 1.9
--- test_gc.py 2001/10/02 21:24:57 1.10
***************
*** 8,14 ****
name, actual, expected)
! def expect_not(actual, expected, name):
! if actual == expected:
! raise TestFailed, "test_%s: actual %d unexpected" % (name, actual)
def run_test(name, thunk):
--- 8,14 ----
name, actual, expected)
! def expect_nonzero(actual, name):
! if actual == 0:
! raise TestFailed, "test_%s: unexpected zero" % name
def run_test(name, thunk):
***************
*** 49,54 ****
gc.collect()
del A
! expect_not(gc.collect(), 0, "class")
def test_instance():
class A:
--- 49,68 ----
gc.collect()
del A
! expect_nonzero(gc.collect(), "class")
!
! def test_staticclass():
! class A(object):
! __dynamic__ = 0
! gc.collect()
! del A
! expect_nonzero(gc.collect(), "staticclass")
+ def test_dynamicclass():
+ class A(object):
+ __dynamic__ = 1
+ gc.collect()
+ del A
+ expect_nonzero(gc.collect(), "dynamicclass")
+
def test_instance():
class A:
***************
*** 58,62 ****
gc.collect()
del a
! expect_not(gc.collect(), 0, "instance")
def test_method():
--- 72,76 ----
gc.collect()
del a
! expect_nonzero(gc.collect(), "instance")
def test_method():
***************
*** 68,72 ****
gc.collect()
del a
! expect_not(gc.collect(), 0, "method")
def test_finalizer():
--- 82,86 ----
gc.collect()
del a
! expect_nonzero(gc.collect(), "method")
def test_finalizer():
***************
*** 85,89 ****
del a
del b
! expect_not(gc.collect(), 0, "finalizer")
for obj in gc.garbage:
if id(obj) == id_a:
--- 99,103 ----
del a
del b
! expect_nonzero(gc.collect(), "finalizer")
for obj in gc.garbage:
if id(obj) == id_a:
***************
*** 154,157 ****
--- 168,173 ----
run_test("tuples", test_tuple)
run_test("classes", test_class)
+ run_test("static classes", test_staticclass)
+ run_test("dynamic classes", test_dynamicclass)
run_test("instances", test_instance)
run_test("methods", test_method)