From a57df2cf1d627840dff505e8487fbd5f42414c7b Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Wed, 31 Mar 2010 21:32:15 +0000 Subject: Issue #8268: Old-style classes (not just instances) now support weak references. --- Include/classobject.h | 1 + Lib/test/test_sys.py | 2 +- Lib/test/test_weakref.py | 20 ++++++++++++++++++++ Misc/NEWS | 3 +++ Objects/classobject.c | 5 ++++- 5 files changed, 29 insertions(+), 2 deletions(-) diff --git a/Include/classobject.h b/Include/classobject.h index 118dd09..bc03e0d 100644 --- a/Include/classobject.h +++ b/Include/classobject.h @@ -18,6 +18,7 @@ typedef struct { PyObject *cl_getattr; PyObject *cl_setattr; PyObject *cl_delattr; + PyObject *cl_weakreflist; /* List of weak references */ } PyClassObject; typedef struct { diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index d106fe7..1720875 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -544,7 +544,7 @@ class SizeofTest(unittest.TestCase): class class_oldstyle(): def method(): pass - check(class_oldstyle, size(h + '6P')) + check(class_oldstyle, size(h + '7P')) # instance (old-style class) check(class_oldstyle(), size(h + '3P')) # instancemethod (old-style class) diff --git a/Lib/test/test_weakref.py b/Lib/test/test_weakref.py index 536a987..bc2982f 100644 --- a/Lib/test/test_weakref.py +++ b/Lib/test/test_weakref.py @@ -685,6 +685,26 @@ class ReferencesTestCase(TestBase): # No exception should be raised here gc.collect() + def test_classes(self): + # Check that both old-style classes and new-style classes + # are weakrefable. + class A(object): + pass + class B: + pass + l = [] + weakref.ref(int) + a = weakref.ref(A, l.append) + A = None + gc.collect() + self.assertEqual(a(), None) + self.assertEqual(l, [a]) + b = weakref.ref(B, l.append) + B = None + gc.collect() + self.assertEqual(b(), None) + self.assertEqual(l, [a, b]) + class SubclassableWeakrefTestCase(TestBase): diff --git a/Misc/NEWS b/Misc/NEWS index 09d07f2..80f1d2e 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -12,6 +12,9 @@ What's New in Python 2.7 beta 1? Core and Builtins ----------------- +- Issue #8268: Old-style classes (not just instances) now support weak + references. + - Issue #8211: Save/restore CFLAGS around AC_PROG_CC in configure.in, compiler optimizations are disabled when --with-pydebug is used. diff --git a/Objects/classobject.c b/Objects/classobject.c index 3f51c0f..032d354 100644 --- a/Objects/classobject.c +++ b/Objects/classobject.c @@ -123,6 +123,7 @@ alloc_error: op->cl_dict = dict; Py_XINCREF(name); op->cl_name = name; + op->cl_weakreflist = NULL; op->cl_getattr = class_lookup(op, getattrstr, &dummy); op->cl_setattr = class_lookup(op, setattrstr, &dummy); @@ -188,6 +189,8 @@ static void class_dealloc(PyClassObject *op) { _PyObject_GC_UNTRACK(op); + if (op->cl_weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *) op); Py_DECREF(op->cl_bases); Py_DECREF(op->cl_dict); Py_XDECREF(op->cl_name); @@ -454,7 +457,7 @@ PyTypeObject PyClass_Type = { (traverseproc)class_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ + offsetof(PyClassObject, cl_weakreflist), /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ 0, /* tp_methods */ -- cgit v0.12