Skip to content

Commit a57df2c

Browse files
committed
Issue #8268: Old-style classes (not just instances) now support weak
references.
1 parent 26cc99d commit a57df2c

5 files changed

Lines changed: 29 additions & 2 deletions

File tree

‎Include/classobject.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ typedef struct {
1818
PyObject *cl_getattr;
1919
PyObject *cl_setattr;
2020
PyObject *cl_delattr;
21+
PyObject *cl_weakreflist; /* List of weak references */
2122
} PyClassObject;
2223

2324
typedef struct {

‎Lib/test/test_sys.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,7 @@ def inner():
544544
class class_oldstyle():
545545
def method():
546546
pass
547-
check(class_oldstyle, size(h + '6P'))
547+
check(class_oldstyle, size(h + '7P'))
548548
# instance (old-style class)
549549
check(class_oldstyle(), size(h + '3P'))
550550
# instancemethod (old-style class)

‎Lib/test/test_weakref.py‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,26 @@ def test_init(self):
685685
# No exception should be raised here
686686
gc.collect()
687687

688+
def test_classes(self):
689+
# Check that both old-style classes and new-style classes
690+
# are weakrefable.
691+
class A(object):
692+
pass
693+
class B:
694+
pass
695+
l = []
696+
weakref.ref(int)
697+
a = weakref.ref(A, l.append)
698+
A = None
699+
gc.collect()
700+
self.assertEqual(a(), None)
701+
self.assertEqual(l, [a])
702+
b = weakref.ref(B, l.append)
703+
B = None
704+
gc.collect()
705+
self.assertEqual(b(), None)
706+
self.assertEqual(l, [a, b])
707+
688708

689709
class SubclassableWeakrefTestCase(TestBase):
690710

‎Misc/NEWS‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ What's New in Python 2.7 beta 1?
1212
Core and Builtins
1313
-----------------
1414

15+
- Issue #8268: Old-style classes (not just instances) now support weak
16+
references.
17+
1518
- Issue #8211: Save/restore CFLAGS around AC_PROG_CC in configure.in, compiler
1619
optimizations are disabled when --with-pydebug is used.
1720

‎Objects/classobject.c‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ PyClass_New(PyObject *bases, PyObject *dict, PyObject *name)
123123
op->cl_dict = dict;
124124
Py_XINCREF(name);
125125
op->cl_name = name;
126+
op->cl_weakreflist = NULL;
126127

127128
op->cl_getattr = class_lookup(op, getattrstr, &dummy);
128129
op->cl_setattr = class_lookup(op, setattrstr, &dummy);
@@ -188,6 +189,8 @@ static void
188189
class_dealloc(PyClassObject *op)
189190
{
190191
_PyObject_GC_UNTRACK(op);
192+
if (op->cl_weakreflist != NULL)
193+
PyObject_ClearWeakRefs((PyObject *) op);
191194
Py_DECREF(op->cl_bases);
192195
Py_DECREF(op->cl_dict);
193196
Py_XDECREF(op->cl_name);
@@ -454,7 +457,7 @@ PyTypeObject PyClass_Type = {
454457
(traverseproc)class_traverse, /* tp_traverse */
455458
0, /* tp_clear */
456459
0, /* tp_richcompare */
457-
0, /* tp_weaklistoffset */
460+
offsetof(PyClassObject, cl_weakreflist), /* tp_weaklistoffset */
458461
0, /* tp_iter */
459462
0, /* tp_iternext */
460463
0, /* tp_methods */

0 commit comments

Comments
 (0)