summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_gc.py
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2001-10-02 21:24:57 (GMT)
committerGuido van Rossum <guido@python.org>2001-10-02 21:24:57 (GMT)
commit048eb75c2dca8bf6d483b290c901a53510c9b78a (patch)
tree4ffa13f63991488114f0e5c0d57983c0d80481e3 /Lib/test/test_gc.py
parent0481d24dd51bf3a346b432e1c065ed027bccb5c4 (diff)
downloadcpython-048eb75c2dca8bf6d483b290c901a53510c9b78a.zip
cpython-048eb75c2dca8bf6d483b290c901a53510c9b78a.tar.gz
cpython-048eb75c2dca8bf6d483b290c901a53510c9b78a.tar.bz2
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.)
Diffstat (limited to 'Lib/test/test_gc.py')
-rw-r--r--Lib/test/test_gc.py30
1 files changed, 23 insertions, 7 deletions
diff --git a/Lib/test/test_gc.py b/Lib/test/test_gc.py
index 103b4b7..125521a 100644
--- a/Lib/test/test_gc.py
+++ b/Lib/test/test_gc.py
@@ -7,9 +7,9 @@ def expect(actual, expected, name):
raise TestFailed, "test_%s: actual %d, expected %d" % (
name, actual, expected)
-def expect_not(actual, expected, name):
- if actual == expected:
- raise TestFailed, "test_%s: actual %d unexpected" % (name, actual)
+def expect_nonzero(actual, name):
+ if actual == 0:
+ raise TestFailed, "test_%s: unexpected zero" % name
def run_test(name, thunk):
if verbose:
@@ -48,7 +48,21 @@ def test_class():
A.a = A
gc.collect()
del A
- expect_not(gc.collect(), 0, "class")
+ 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:
@@ -57,7 +71,7 @@ def test_instance():
a.a = a
gc.collect()
del a
- expect_not(gc.collect(), 0, "instance")
+ expect_nonzero(gc.collect(), "instance")
def test_method():
# Tricky: self.__init__ is a bound method, it references the instance.
@@ -67,7 +81,7 @@ def test_method():
a = A()
gc.collect()
del a
- expect_not(gc.collect(), 0, "method")
+ expect_nonzero(gc.collect(), "method")
def test_finalizer():
# A() is uncollectable if it is part of a cycle, make sure it shows up
@@ -84,7 +98,7 @@ def test_finalizer():
gc.collect()
del a
del b
- expect_not(gc.collect(), 0, "finalizer")
+ expect_nonzero(gc.collect(), "finalizer")
for obj in gc.garbage:
if id(obj) == id_a:
del obj.a
@@ -153,6 +167,8 @@ def test_all():
run_test("dicts", test_dict)
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)
run_test("functions", test_function)