Kaydet (Commit) 8998a819 authored tarafından Tim Peters's avatar Tim Peters

Fixed the gc-vs-__del__ bugs for new-style classes. That's it for this one.

üst 1ac38499
......@@ -257,6 +257,48 @@ def test_boom2():
expect(gc.collect(), 4, "boom2")
expect(len(gc.garbage), garbagelen, "boom2")
# boom__new and boom2_new are exactly like boom and boom2, except use
# new-style classes.
class Boom_New(object):
def __getattr__(self, someattribute):
del self.attr
raise AttributeError
def test_boom_new():
a = Boom_New()
b = Boom_New()
a.attr = b
b.attr = a
gc.collect()
garbagelen = len(gc.garbage)
del a, b
expect(gc.collect(), 4, "boom_new")
expect(len(gc.garbage), garbagelen, "boom_new")
class Boom2_New(object):
def __init__(self):
self.x = 0
def __getattr__(self, someattribute):
self.x += 1
if self.x > 1:
del self.attr
raise AttributeError
def test_boom2_new():
a = Boom2_New()
b = Boom2_New()
a.attr = b
b.attr = a
gc.collect()
garbagelen = len(gc.garbage)
del a, b
expect(gc.collect(), 4, "boom2_new")
expect(len(gc.garbage), garbagelen, "boom2_new")
def test_all():
gc.collect() # Delete 2nd generation garbage
run_test("lists", test_list)
......@@ -275,6 +317,8 @@ def test_all():
run_test("trashcan", test_trashcan)
run_test("boom", test_boom)
run_test("boom2", test_boom2)
run_test("boom_new", test_boom_new)
run_test("boom2_new", test_boom2_new)
def test():
if verbose:
......
......@@ -2,6 +2,14 @@ What's New in Python 2.2.3 ?
Release date: XX-XXX-2003
============================
- Some horridly obscure problems were fixed involving interaction
between garbage collection and classes with "ambitious" getattr hooks.
If a class instance didn't have a __del__ method, but did have a
__getattr__ hook, and the instance became reachable only from an
unreachable cycle, and the hook resurrected or deleted unreachable
objects when asked to resolve "__del__", anything up to a segfault
could happen. That's been repaired.
- Skip locale test on Mac OS X.
- Backported the "largefile" requirement for test_largefile on Mac OS X.
......
......@@ -259,7 +259,6 @@ move_root_reachable(PyGC_Head *reachable)
* could call the class's __getattr__ hook (if any). That could invoke
* arbitrary Python code, mutating the object graph in arbitrary ways, and
* that was the source of some excruciatingly subtle bugs.
* XXX This is still broken for new-style classes.
*/
static int
has_finalizer(PyObject *op)
......@@ -274,8 +273,7 @@ has_finalizer(PyObject *op)
if (PyInstance_Check(op))
return _PyInstance_Lookup(op, delstr) != NULL;
else if (PyType_HasFeature(op->ob_type, Py_TPFLAGS_HEAPTYPE))
/* XXX This path is still Evil. */
return PyObject_HasAttr(op, delstr);
return _PyType_Lookup(op->ob_type, delstr) != NULL;
else
return 0;
}
......@@ -284,20 +282,18 @@ has_finalizer(PyObject *op)
static void
move_finalizers(PyGC_Head *unreachable, PyGC_Head *finalizers)
{
PyGC_Head *next;
PyGC_Head *gc = unreachable->gc.gc_next;
for (; gc != unreachable; gc=next) {
while (gc != unreachable) {
PyGC_Head *next = gc->gc.gc_next;
PyObject *op = FROM_GC(gc);
/* XXX has_finalizer() may result in arbitrary Python
code being run. */
if (has_finalizer(op)) {
next = gc->gc.gc_next;
gc_list_remove(gc);
gc_list_append(gc, finalizers);
gc->gc.gc_refs = GC_MOVED;
}
else
next = gc->gc.gc_next;
gc = next;
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment