]> granicus.if.org Git - python/commitdiff
Issue #8268: Old-style classes (not just instances) now support weak
authorAntoine Pitrou <solipsis@pitrou.net>
Wed, 31 Mar 2010 21:32:15 +0000 (21:32 +0000)
committerAntoine Pitrou <solipsis@pitrou.net>
Wed, 31 Mar 2010 21:32:15 +0000 (21:32 +0000)
references.

Include/classobject.h
Lib/test/test_sys.py
Lib/test/test_weakref.py
Misc/NEWS
Objects/classobject.c

index 118dd09647a379f7a1568e57542e06d895c0b0ea..bc03e0d0270dc32fe4e03418355a0c558fd901a0 100644 (file)
@@ -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 {
index d106fe7a7a79d3a504eda623567eb8aa6f2019f7..17208753bebf8b706cca913a48d18357090c654f 100644 (file)
@@ -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)
index 536a987fe4f2b6579b157aa5ce9446bd32c9ac46..bc2982fadbcdbe89be8f4a96767a307fc3d9be8c 100644 (file)
@@ -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):
 
index 09d07f2c3b3d7ae0926d1371e4d106a83bf66b72..80f1d2e2e03493b6572833b2748fe46f54060690 100644 (file)
--- 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.
 
index 3f51c0fc55cc4aa5d6596e92913764a53c290cd3..032d354ef0cf60cb9e96fea607f41ae092fcfaab 100644 (file)
@@ -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 */