diff --git a/psycopg/connection_type.c b/psycopg/connection_type.c index 3cdbf1fc..a7be6582 100644 --- a/psycopg/connection_type.c +++ b/psycopg/connection_type.c @@ -450,11 +450,11 @@ connection_dealloc(PyObject* obj) if (self->encoding) free(self->encoding); if (self->critical) free(self->critical); - Py_XDECREF(self->notice_list); - Py_XDECREF(self->notifies); - Py_XDECREF(self->async_cursor); - Py_XDECREF(self->string_types); - Py_XDECREF(self->binary_types); + Py_CLEAR(self->notice_list); + Py_CLEAR(self->notifies); + Py_CLEAR(self->async_cursor); + Py_CLEAR(self->string_types); + Py_CLEAR(self->binary_types); pthread_mutex_destroy(&(self->lock)); @@ -486,7 +486,7 @@ connection_new(PyTypeObject *type, PyObject *args, PyObject *kwds) static void connection_del(PyObject* self) { - PyObject_Del(self); + PyObject_GC_Del(self); } static PyObject * @@ -497,6 +497,18 @@ connection_repr(connectionObject *self) self, self->dsn, self->closed); } +static int +connection_traverse(connectionObject *self, visitproc visit, void *arg) +{ + Py_VISIT(self->async_cursor); + Py_VISIT(self->notice_list); + Py_VISIT(self->notice_filter); + Py_VISIT(self->notifies); + Py_VISIT(self->string_types); + Py_VISIT(self->binary_types); + return 0; +} + /* object type */ @@ -530,10 +542,10 @@ PyTypeObject connectionType = { 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ connectionType_doc, /*tp_doc*/ - 0, /*tp_traverse*/ + (traverseproc)connection_traverse, /*tp_traverse*/ 0, /*tp_clear*/ 0, /*tp_richcompare*/ diff --git a/psycopg/cursor_type.c b/psycopg/cursor_type.c index 5b0cd026..03be9d90 100644 --- a/psycopg/cursor_type.c +++ b/psycopg/cursor_type.c @@ -1634,15 +1634,15 @@ cursor_dealloc(PyObject* obj) if (self->name) PyMem_Free(self->name); - Py_XDECREF((PyObject*)self->conn); - Py_XDECREF(self->casts); - Py_XDECREF(self->description); - Py_XDECREF(self->pgstatus); - Py_XDECREF(self->tuple_factory); - Py_XDECREF(self->tzinfo_factory); - Py_XDECREF(self->query); - Py_XDECREF(self->string_types); - Py_XDECREF(self->binary_types); + Py_CLEAR(self->conn); + Py_CLEAR(self->casts); + Py_CLEAR(self->description); + Py_CLEAR(self->pgstatus); + Py_CLEAR(self->tuple_factory); + Py_CLEAR(self->tzinfo_factory); + Py_CLEAR(self->query); + Py_CLEAR(self->string_types); + Py_CLEAR(self->binary_types); IFCLEARPGRES(self->pgres); @@ -1675,7 +1675,7 @@ cursor_new(PyTypeObject *type, PyObject *args, PyObject *kwds) static void cursor_del(PyObject* self) { - PyObject_Del(self); + PyObject_GC_Del(self); } static PyObject * @@ -1685,6 +1685,23 @@ cursor_repr(cursorObject *self) "", self, self->closed); } +static int +cursor_traverse(cursorObject *self, visitproc visit, void *arg) +{ + Py_VISIT(self->conn); + Py_VISIT(self->description); + Py_VISIT(self->pgstatus); + Py_VISIT(self->casts); + Py_VISIT(self->caster); + Py_VISIT(self->copyfile); + Py_VISIT(self->tuple_factory); + Py_VISIT(self->tzinfo_factory); + Py_VISIT(self->query); + Py_VISIT(self->string_types); + Py_VISIT(self->binary_types); + return 0; +} + /* object type */ @@ -1714,10 +1731,11 @@ PyTypeObject cursorType = { 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_ITER, /*tp_flags*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_ITER | + Py_TPFLAGS_HAVE_GC, /*tp_flags*/ cursorType_doc, /*tp_doc*/ - 0, /*tp_traverse*/ + (traverseproc)cursor_traverse, /*tp_traverse*/ 0, /*tp_clear*/ 0, /*tp_richcompare*/ diff --git a/psycopg/python.h b/psycopg/python.h index 84bacaa2..13d6ce79 100644 --- a/psycopg/python.h +++ b/psycopg/python.h @@ -41,4 +41,27 @@ #define freefunc destructor #endif +/* Py_VISIT and Py_CLEAR introduced in Python 2.4 */ +#ifndef Py_VISIT +#define Py_VISIT(op) \ + do { \ + if (op) { \ + int vret = visit((op), arg); \ + if (vret) \ + return vret; \ + } \ + } while (0) +#endif + +#ifndef Py_CLEAR +#define Py_CLEAR(op) \ + do { \ + if (op) { \ + PyObject *tmp = (PyObject *)(op); \ + (op) = NULL; \ + Py_DECREF(tmp); \ + } \ + } while (0) +#endif + #endif /* !defined(PSYCOPG_PYTHON_H) */