[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)