-diff -up Python-2.7.3/Lib/test/test_gc.py.gc-assertions Python-2.7.3/Lib/test/test_gc.py
---- Python-2.7.3/Lib/test/test_gc.py.gc-assertions 2013-02-20 16:28:20.890536607 -0500
-+++ Python-2.7.3/Lib/test/test_gc.py 2013-02-20 16:39:52.720489297 -0500
-@@ -1,6 +1,7 @@
+diff --git a/Lib/test/test_gc.py b/Lib/test/test_gc.py
+index 7e47b2d..12a210d 100644
+--- a/Lib/test/test_gc.py
++++ b/Lib/test/test_gc.py
+@@ -1,7 +1,8 @@
import unittest
--from test.test_support import verbose, run_unittest, start_threads
-+from test.test_support import verbose, run_unittest, start_threads, import_module
+ from test.support import (verbose, run_unittest, start_threads,
+- requires_type_collecting)
++ requires_type_collecting, import_module)
import sys
+import sysconfig
import time
import gc
import weakref
-@@ -32,6 +33,8 @@ class GC_Detector(object):
+@@ -39,6 +40,8 @@ class GC_Detector(object):
self.wr = weakref.ref(C1055820(666), it_happened)
### Tests
###############################################################################
-@@ -476,6 +479,49 @@ class GCTests(unittest.TestCase):
+@@ -537,6 +540,49 @@ class GCTests(unittest.TestCase):
# would be damaged, with an empty __dict__.
self.assertEqual(x, None)
class GCTogglingTests(unittest.TestCase):
def setUp(self):
gc.enable()
-diff -up Python-2.7.3/Modules/gcmodule.c.gc-assertions Python-2.7.3/Modules/gcmodule.c
---- Python-2.7.3/Modules/gcmodule.c.gc-assertions 2012-04-09 19:07:34.000000000 -0400
-+++ Python-2.7.3/Modules/gcmodule.c 2013-02-20 16:28:21.029536600 -0500
+diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c
+index 916e481..0233ce2 100644
+--- a/Modules/gcmodule.c
++++ b/Modules/gcmodule.c
@@ -21,6 +21,73 @@
#include "Python.h"
#include "frameobject.h" /* for PyFrame_ClearFreeList */
/* Get an object's GC head */
#define AS_GC(o) ((PyGC_Head *)(o)-1)
-@@ -288,7 +355,8 @@ update_refs(PyGC_Head *containers)
+@@ -328,7 +395,8 @@ update_refs(PyGC_Head *containers)
{
PyGC_Head *gc = containers->gc.gc_next;
for (; gc != containers; gc = gc->gc.gc_next) {
gc->gc.gc_refs = Py_REFCNT(FROM_GC(gc));
/* Python's cyclic gc should never see an incoming refcount
* of 0: if something decref'ed to 0, it should have been
-@@ -308,7 +376,8 @@ update_refs(PyGC_Head *containers)
+@@ -348,7 +416,8 @@ update_refs(PyGC_Head *containers)
* so serious that maybe this should be a release-build
* check instead of an assert?
*/
}
}
-@@ -323,7 +392,9 @@ visit_decref(PyObject *op, void *data)
+@@ -363,7 +432,9 @@ visit_decref(PyObject *op, void *data)
* generation being collected, which can be recognized
* because only they have positive gc_refs.
*/
if (gc->gc.gc_refs > 0)
gc->gc.gc_refs--;
}
-@@ -383,9 +454,10 @@ visit_reachable(PyObject *op, PyGC_Head
+@@ -423,9 +494,10 @@ visit_reachable(PyObject *op, PyGC_Head *reachable)
* If gc_refs == GC_UNTRACKED, it must be ignored.
*/
else {
}
}
return 0;
-@@ -427,7 +499,7 @@ move_unreachable(PyGC_Head *young, PyGC_
+@@ -467,7 +539,7 @@ move_unreachable(PyGC_Head *young, PyGC_Head *unreachable)
*/
PyObject *op = FROM_GC(gc);
traverseproc traverse = Py_TYPE(op)->tp_traverse;
gc->gc.gc_refs = GC_REACHABLE;
(void) traverse(op,
(visitproc)visit_reachable,
-@@ -494,7 +566,8 @@ move_finalizers(PyGC_Head *unreachable,
+@@ -545,7 +617,8 @@ move_finalizers(PyGC_Head *unreachable, PyGC_Head *finalizers)
for (gc = unreachable->gc.gc_next; gc != unreachable; gc = next) {
PyObject *op = FROM_GC(gc);
next = gc->gc.gc_next;
if (has_finalizer(op)) {
-@@ -570,7 +643,7 @@ handle_weakrefs(PyGC_Head *unreachable,
+@@ -621,7 +694,7 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old)
PyWeakReference **wrlist;
op = FROM_GC(gc);
next = gc->gc.gc_next;
if (! PyType_SUPPORTS_WEAKREFS(Py_TYPE(op)))
-@@ -591,9 +664,9 @@ handle_weakrefs(PyGC_Head *unreachable,
+@@ -642,9 +715,9 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old)
* the callback pointer intact. Obscure: it also
* changes *wrlist.
*/
if (wr->wr_callback == NULL)
continue; /* no callback */
-@@ -627,7 +700,7 @@ handle_weakrefs(PyGC_Head *unreachable,
+@@ -678,7 +751,7 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old)
*/
if (IS_TENTATIVELY_UNREACHABLE(wr))
continue;
/* Create a new reference so that wr can't go away
* before we can process it again.
-@@ -636,7 +709,8 @@ handle_weakrefs(PyGC_Head *unreachable,
+@@ -687,7 +760,8 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old)
/* Move wr to wrcb_to_call, for the next pass. */
wrasgc = AS_GC(wr);
next isn't, so they can't
be the same */
gc_list_move(wrasgc, &wrcb_to_call);
-@@ -652,11 +726,11 @@ handle_weakrefs(PyGC_Head *unreachable,
+@@ -703,11 +777,11 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old)
gc = wrcb_to_call.gc.gc_next;
op = FROM_GC(gc);
/* copy-paste of weakrefobject.c's handle_callback() */
temp = PyObject_CallFunctionObjArgs(callback, wr, NULL);
-@@ -759,7 +833,7 @@ delete_garbage(PyGC_Head *collectable, P
+@@ -810,7 +884,7 @@ delete_garbage(PyGC_Head *collectable, PyGC_Head *old)
PyGC_Head *gc = collectable->gc.gc_next;
PyObject *op = FROM_GC(gc);