]> granicus.if.org Git - python/commitdiff
Make sets and deques weak referencable.
authorRaymond Hettinger <python@rcn.com>
Sun, 30 May 2004 07:26:47 +0000 (07:26 +0000)
committerRaymond Hettinger <python@rcn.com>
Sun, 30 May 2004 07:26:47 +0000 (07:26 +0000)
Include/setobject.h
Lib/test/test_deque.py
Lib/test/test_set.py
Modules/collectionsmodule.c
Objects/setobject.c

index 267e3b0956552d33126936d5a3b190fe83448039..abbd8477ad83bcd277c8f9f6627520c0e88d6d45 100644 (file)
@@ -15,6 +15,7 @@ typedef struct {
        PyObject_HEAD
        PyObject *data;
        long hash;      /* only used by frozenset objects */
+       PyObject *weakreflist; /* List of weak references */
 } PySetObject;
 
 PyAPI_DATA(PyTypeObject) PySet_Type;
index bad885761e2d90aac5863d331482403c214ab2c2..13800ea215f2879f351d3877be08b8b9378f8e47 100644 (file)
@@ -1,6 +1,7 @@
 from collections import deque
 import unittest
 from test import test_support
+from weakref import proxy
 import copy
 import cPickle as pickle
 from cStringIO import StringIO
@@ -435,6 +436,12 @@ class TestSubclass(unittest.TestCase):
         self.assertEqual(type(d), type(e))
         self.assertEqual(list(d), list(e))
 
+    def test_weakref(self):
+        d = deque('gallahad')
+        p = proxy(d)
+        self.assertEqual(str(p), str(d))
+        d = None
+        self.assertRaises(ReferenceError, str, p)
 
 #==============================================================================
 
index 3a85c767a81397d63800198b337986e7880228aa..514b75c0d69cfaec4abe3c91fc2e5f78a8965b54 100644 (file)
@@ -1,5 +1,6 @@
 import unittest
 from test import test_support
+from weakref import proxy
 import operator
 import copy
 import pickle
@@ -346,6 +347,13 @@ class TestSet(TestJointOps):
             else:
                 self.assert_(c not in self.s)
 
+    def test_weakref(self):
+        s = self.thetype('gallahad')
+        p = proxy(s)
+        self.assertEqual(str(p), str(s))
+        s = None
+        self.assertRaises(ReferenceError, str, p)
+
 class SetSubclass(set):
     pass
 
index 368f0b6ca0962cb8946d3f0909be42ca7c329e27..62b43aa90e45bbbd2e9763b7dfc134c845521286 100644 (file)
@@ -1,4 +1,5 @@
 #include "Python.h"
+#include "structmember.h"
 
 /* collections module implementation of a deque() datatype
    Written and maintained by Raymond D. Hettinger <python@rcn.com>
@@ -32,6 +33,7 @@ typedef struct {
        int leftindex;
        int rightindex;
        int len;
+       PyObject *weakreflist; /* List of weak references */
 } dequeobject;
 
 static PyTypeObject deque_type;
@@ -58,6 +60,7 @@ deque_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
        deque->leftindex = BLOCKLEN / 2 + 1;
        deque->rightindex = BLOCKLEN / 2;
        deque->len = 0;
+       deque->weakreflist = NULL;
 
        return (PyObject *)deque;
 }
@@ -439,6 +442,8 @@ static void
 deque_dealloc(dequeobject *deque)
 {
        PyObject_GC_UnTrack(deque);
+       if (deque->weakreflist != NULL)
+               PyObject_ClearWeakRefs((PyObject *) deque);
        if (deque->leftblock != NULL) {
                int err = deque_clear(deque);
                assert(err == 0);
@@ -744,12 +749,13 @@ static PyTypeObject deque_type = {
        PyObject_GenericGetAttr,        /* tp_getattro */
        0,                              /* tp_setattro */
        0,                              /* tp_as_buffer */
-       Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,  /* tp_flags */
+       Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
+               Py_TPFLAGS_HAVE_WEAKREFS,       /* tp_flags */
        deque_doc,                      /* tp_doc */
        (traverseproc)deque_traverse,   /* tp_traverse */
        (inquiry)deque_clear,           /* tp_clear */
        (richcmpfunc)deque_richcompare, /* tp_richcompare */
-       0,                              /* tp_weaklistoffset*/
+       offsetof(dequeobject, weakreflist),     /* tp_weaklistoffset*/
        (getiterfunc)deque_iter,        /* tp_iter */
        0,                              /* tp_iternext */
        deque_methods,                  /* tp_methods */
index 9aedc2f162b1a470ad87f7b3ecf7599fe5b80c5b..fbff0779c212ac47de7714ab34140db02805a7a5 100644 (file)
@@ -1,4 +1,5 @@
 #include "Python.h"
+#include "structmember.h"
 
 /* set object implementation 
    written and maintained by Raymond D. Hettinger <python@rcn.com>
@@ -61,6 +62,7 @@ make_new_set(PyTypeObject *type, PyObject *iterable)
        }
        so->data = data;
        so->hash = -1;
+       so->weakreflist = NULL;
 
        if (iterable != NULL) {
                tmp = set_update(so, iterable);
@@ -113,6 +115,8 @@ static void
 set_dealloc(PySetObject *so)
 {
        PyObject_GC_UnTrack(so);
+       if (so->weakreflist != NULL)
+               PyObject_ClearWeakRefs((PyObject *) so);
        Py_XDECREF(so->data);
        so->ob_type->tp_free(so);
 }
@@ -1009,12 +1013,12 @@ PyTypeObject PySet_Type = {
        0,                              /* tp_setattro */
        0,                              /* tp_as_buffer */
        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES |
-               Py_TPFLAGS_BASETYPE,    /* tp_flags */
+               Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
        set_doc,                        /* tp_doc */
        (traverseproc)set_traverse,     /* tp_traverse */
        (inquiry)set_tp_clear,          /* tp_clear */
        (richcmpfunc)set_richcompare,   /* tp_richcompare */
-       0,                              /* tp_weaklistoffset */
+       offsetof(PySetObject, weakreflist),     /* tp_weaklistoffset */
        (getiterfunc)set_iter,          /* tp_iter */
        0,                              /* tp_iternext */
        set_methods,                    /* tp_methods */
@@ -1104,12 +1108,12 @@ PyTypeObject PyFrozenSet_Type = {
        0,                              /* tp_setattro */
        0,                              /* tp_as_buffer */
        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES |
-               Py_TPFLAGS_BASETYPE,    /* tp_flags */
+               Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
        frozenset_doc,                  /* tp_doc */
        (traverseproc)set_traverse,     /* tp_traverse */
        0,                              /* tp_clear */
        (richcmpfunc)set_richcompare,   /* tp_richcompare */
-       0,                              /* tp_weaklistoffset */
+       offsetof(PySetObject, weakreflist),     /* tp_weaklistoffset */
        (getiterfunc)set_iter,          /* tp_iter */
        0,                              /* tp_iternext */
        frozenset_methods,              /* tp_methods */