From 19ff51ae75914c2226888ac1a3ffecdc590d0ec7 Mon Sep 17 00:00:00 2001 From: Daniele Varrazzo Date: Mon, 3 Jan 2011 12:47:01 +0100 Subject: [PATCH] The cursor is weakly referenceable --- NEWS-2.3 | 2 +- psycopg/cursor.h | 2 ++ psycopg/cursor_type.c | 12 +++++++++--- tests/test_cursor.py | 7 +++++++ 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/NEWS-2.3 b/NEWS-2.3 index 82b87594..a2096bac 100644 --- a/NEWS-2.3 +++ b/NEWS-2.3 @@ -6,7 +6,7 @@ What's new in psycopg 2.3.3 - Added `register_composite()` function to cast PostgreSQL composite types into Python tuples/namedtuples. - The build script refuses to guess values if pg_config is not found. - - Connections are weakly referenceable. + - Connections and cursors are weakly referenceable. * Bug fixes: diff --git a/psycopg/cursor.h b/psycopg/cursor.h index 107ddb3a..96a133fa 100644 --- a/psycopg/cursor.h +++ b/psycopg/cursor.h @@ -81,6 +81,8 @@ typedef struct { PyObject *string_types; /* a set of typecasters for string types */ PyObject *binary_types; /* a set of typecasters for binary types */ + PyObject *weakreflist; /* list of weak references */ + } cursorObject; /* C-callable functions in cursor_int.c and cursor_ext.c */ diff --git a/psycopg/cursor_type.c b/psycopg/cursor_type.c index b531ad3e..be22e34f 100644 --- a/psycopg/cursor_type.c +++ b/psycopg/cursor_type.c @@ -1642,6 +1642,7 @@ cursor_setup(cursorObject *self, connectionObject *conn, const char *name) self->string_types = NULL; self->binary_types = NULL; + self->weakreflist = NULL; Py_INCREF(Py_None); self->description = Py_None; @@ -1667,7 +1668,11 @@ static void cursor_dealloc(PyObject* obj) { cursorObject *self = (cursorObject *)obj; - + + if (self->weakreflist) { + PyObject_ClearWeakRefs(obj); + } + PyObject_GC_UnTrack(self); if (self->name) PyMem_Free(self->name); @@ -1769,14 +1774,15 @@ PyTypeObject cursorType = { 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_ITER | - Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_WEAKREFS , + /*tp_flags*/ cursorType_doc, /*tp_doc*/ (traverseproc)cursor_traverse, /*tp_traverse*/ 0, /*tp_clear*/ 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ + offsetof(cursorObject, weakreflist), /*tp_weaklistoffset*/ cursor_iter, /*tp_iter*/ cursor_next, /*tp_iternext*/ diff --git a/tests/test_cursor.py b/tests/test_cursor.py index ad458702..e5dd39b9 100644 --- a/tests/test_cursor.py +++ b/tests/test_cursor.py @@ -99,6 +99,13 @@ class CursorTests(unittest.TestCase): curs2 = self.conn.cursor() self.assertEqual("foofoo", curs2.cast(705, 'foo')) + def test_weakref(self): + from weakref import ref + curs = self.conn.cursor() + w = ref(curs) + del curs + self.assert_(w() is None) + def test_suite(): return unittest.TestLoader().loadTestsFromName(__name__)