From 6ece632c6bdea264ea23b0669ac12f7ad38b1e47 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 20 Jan 2021 21:55:27 +0100 Subject: [PATCH 01/14] sqlite.Connection type now implements GC protocol --- Modules/_sqlite/connection.c | 52 ++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 28932726b74257..27d58dfc0060fa 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -225,28 +225,51 @@ pysqlite_do_all_statements(pysqlite_Connection *self, int action, } } +static int +connection_traverse(pysqlite_Connection *self, visitproc visit, void *arg) +{ + Py_VISIT(self->statement_cache); + Py_VISIT(self->function_pinboard_trace_callback); + Py_VISIT(self->function_pinboard_progress_handler); + Py_VISIT(self->function_pinboard_authorizer_cb); + Py_VISIT(self->row_factory); + Py_VISIT(self->text_factory); + Py_VISIT(self->collations); + Py_VISIT(self->statements); + Py_VISIT(self->cursors); + Py_VISIT(Py_TYPE(self)); + return 0; +} + +static int +connection_clear(pysqlite_Connection *self) +{ + Py_CLEAR(self->statement_cache); + Py_CLEAR(self->isolation_level); + Py_CLEAR(self->function_pinboard_trace_callback); + Py_CLEAR(self->function_pinboard_progress_handler); + Py_CLEAR(self->function_pinboard_authorizer_cb); + Py_CLEAR(self->row_factory); + Py_CLEAR(self->text_factory); + Py_CLEAR(self->collations); + Py_CLEAR(self->statements); + Py_CLEAR(self->cursors); + return 0; +} + static void pysqlite_connection_dealloc(pysqlite_Connection *self) { PyTypeObject *tp = Py_TYPE(self); - - Py_XDECREF(self->statement_cache); + PyObject_GC_UnTrack(self); + tp->tp_clear((PyObject *)self); /* Clean up if user has not called .close() explicitly. */ if (self->db) { sqlite3_close_v2(self->db); + self->db = NULL; } - Py_XDECREF(self->isolation_level); - Py_XDECREF(self->function_pinboard_trace_callback); - Py_XDECREF(self->function_pinboard_progress_handler); - Py_XDECREF(self->function_pinboard_authorizer_cb); - Py_XDECREF(self->row_factory); - Py_XDECREF(self->text_factory); - Py_XDECREF(self->collations); - Py_XDECREF(self->statements); - Py_XDECREF(self->cursors); - tp->tp_free(self); Py_DECREF(tp); } @@ -1914,16 +1937,17 @@ static PyType_Slot connection_slots[] = { {Py_tp_methods, connection_methods}, {Py_tp_members, connection_members}, {Py_tp_getset, connection_getset}, - {Py_tp_new, PyType_GenericNew}, {Py_tp_init, pysqlite_connection_init}, {Py_tp_call, pysqlite_connection_call}, + {Py_tp_traverse, connection_traverse}, + {Py_tp_clear, connection_clear}, {0, NULL}, }; static PyType_Spec connection_spec = { .name = MODULE_NAME ".Connection", .basicsize = sizeof(pysqlite_Connection), - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, .slots = connection_slots, }; From 866060958c17a4ab6f677362ac357433dc6fca91 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 20 Jan 2021 21:58:56 +0100 Subject: [PATCH 02/14] sqlite.Cursor type now implements GC protocol --- Modules/_sqlite/cursor.c | 44 +++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index b71f780a0b4dfd..9861460ad80fe7 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -81,27 +81,46 @@ pysqlite_cursor_init_impl(pysqlite_Cursor *self, return 0; } -static void pysqlite_cursor_dealloc(pysqlite_Cursor* self) +static int +cursor_traverse(pysqlite_Cursor *self, visitproc visit, void *arg) { - PyTypeObject *tp = Py_TYPE(self); + Py_VISIT(self->connection); + Py_VISIT(self->row_cast_map); + Py_VISIT(self->row_factory); + Py_VISIT(self->next_row); + Py_VISIT(Py_TYPE(self)); + return 0; +} +static int +cursor_clear(pysqlite_Cursor *self) +{ /* Reset the statement if the user has not closed the cursor */ if (self->statement) { pysqlite_statement_reset(self->statement); - Py_DECREF(self->statement); + Py_CLEAR(self->statement); } - Py_XDECREF(self->connection); - Py_XDECREF(self->row_cast_map); - Py_XDECREF(self->description); - Py_XDECREF(self->lastrowid); - Py_XDECREF(self->row_factory); - Py_XDECREF(self->next_row); + Py_CLEAR(self->connection); + Py_CLEAR(self->row_cast_map); + Py_CLEAR(self->description); + Py_CLEAR(self->lastrowid); + Py_CLEAR(self->row_factory); + Py_CLEAR(self->next_row); if (self->in_weakreflist != NULL) { PyObject_ClearWeakRefs((PyObject*)self); } + return 0; +} + +static void +cursor_dealloc(pysqlite_Cursor *self) +{ + PyTypeObject *tp = Py_TYPE(self); + PyObject_GC_UnTrack(self); + tp->tp_clear((PyObject *)self); tp->tp_free(self); Py_DECREF(tp); } @@ -1006,21 +1025,22 @@ static const char cursor_doc[] = PyDoc_STR("SQLite database cursor class."); static PyType_Slot cursor_slots[] = { - {Py_tp_dealloc, pysqlite_cursor_dealloc}, + {Py_tp_dealloc, cursor_dealloc}, {Py_tp_doc, (void *)cursor_doc}, {Py_tp_iter, PyObject_SelfIter}, {Py_tp_iternext, pysqlite_cursor_iternext}, {Py_tp_methods, cursor_methods}, {Py_tp_members, cursor_members}, - {Py_tp_new, PyType_GenericNew}, {Py_tp_init, pysqlite_cursor_init}, + {Py_tp_traverse, cursor_traverse}, + {Py_tp_clear, cursor_clear}, {0, NULL}, }; static PyType_Spec cursor_spec = { .name = MODULE_NAME ".Cursor", .basicsize = sizeof(pysqlite_Cursor), - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, .slots = cursor_slots, }; From 13bc519a06221896f7c2bf0718743a4f1d61bc73 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 20 Jan 2021 22:00:41 +0100 Subject: [PATCH 03/14] sqlite.Row type now implements GC protocol --- Modules/_sqlite/row.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/Modules/_sqlite/row.c b/Modules/_sqlite/row.c index f9dfcbd5d615e5..d314c65370d34b 100644 --- a/Modules/_sqlite/row.c +++ b/Modules/_sqlite/row.c @@ -31,14 +31,27 @@ class _sqlite3.Row "pysqlite_Row *" "pysqlite_RowType" [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=384227da65f250fd]*/ -static void -pysqlite_row_dealloc(pysqlite_Row *self) +static int +row_clear(pysqlite_Row *self) { - PyTypeObject *tp = Py_TYPE(self); + Py_CLEAR(self->data); + Py_CLEAR(self->description); + return 0; +} - Py_XDECREF(self->data); - Py_XDECREF(self->description); +static int +row_traverse(pysqlite_Row *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + return 0; +} +static void +pysqlite_row_dealloc(PyObject *self) +{ + PyTypeObject *tp = Py_TYPE(self); + PyObject_GC_UnTrack(self); + tp->tp_clear(self); tp->tp_free(self); Py_DECREF(tp); } @@ -231,13 +244,15 @@ static PyType_Slot row_slots[] = { {Py_sq_length, pysqlite_row_length}, {Py_sq_item, pysqlite_row_item}, {Py_tp_new, pysqlite_row_new}, + {Py_tp_traverse, row_traverse}, + {Py_tp_clear, row_clear}, {0, NULL}, }; static PyType_Spec row_spec = { .name = MODULE_NAME ".Row", .basicsize = sizeof(pysqlite_Row), - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, .slots = row_slots, }; From 4519017e100f2deed5db367c2e68ec3b2dcd657d Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 20 Jan 2021 22:01:55 +0100 Subject: [PATCH 04/14] sqlite.PrepareProtocol type now implements GC protocol --- Modules/_sqlite/prepare_protocol.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Modules/_sqlite/prepare_protocol.c b/Modules/_sqlite/prepare_protocol.c index 7d2d7ade591467..ece42f4df6f5ac 100644 --- a/Modules/_sqlite/prepare_protocol.c +++ b/Modules/_sqlite/prepare_protocol.c @@ -30,26 +30,33 @@ pysqlite_prepare_protocol_init(pysqlite_PrepareProtocol *self, PyObject *args, return 0; } +static int +pysqlite_prepare_protocol_traverse(PyObject *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + return 0; +} + static void pysqlite_prepare_protocol_dealloc(pysqlite_PrepareProtocol *self) { PyTypeObject *tp = Py_TYPE(self); - + PyObject_GC_UnTrack(self); tp->tp_free(self); Py_DECREF(tp); } static PyType_Slot type_slots[] = { {Py_tp_dealloc, pysqlite_prepare_protocol_dealloc}, - {Py_tp_new, PyType_GenericNew}, {Py_tp_init, pysqlite_prepare_protocol_init}, + {Py_tp_traverse, pysqlite_prepare_protocol_traverse}, {0, NULL}, }; static PyType_Spec type_spec = { .name = MODULE_NAME ".PrepareProtocol", .basicsize = sizeof(pysqlite_PrepareProtocol), - .flags = Py_TPFLAGS_DEFAULT, + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, .slots = type_slots, }; From 20da08820134d0d62882d20b13bb0d223af800f3 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 20 Jan 2021 22:10:58 +0100 Subject: [PATCH 05/14] sqlite.Statement type now implements GC protocol --- Modules/_sqlite/connection.c | 2 +- Modules/_sqlite/cursor.c | 2 +- Modules/_sqlite/statement.c | 28 +++++++++++++++++++++------- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 27d58dfc0060fa..0a3e55b6971818 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -1351,7 +1351,7 @@ pysqlite_connection_call(pysqlite_Connection *self, PyObject *args, _pysqlite_drop_unused_statement_references(self); - statement = PyObject_New(pysqlite_Statement, pysqlite_StatementType); + statement = PyObject_GC_New(pysqlite_Statement, pysqlite_StatementType); if (!statement) { return NULL; } diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 9861460ad80fe7..f1d1c8a1bbcf7d 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -506,7 +506,7 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation if (self->statement->in_use) { Py_SETREF(self->statement, - PyObject_New(pysqlite_Statement, pysqlite_StatementType)); + PyObject_GC_New(pysqlite_Statement, pysqlite_StatementType)); if (!self->statement) { goto error; } diff --git a/Modules/_sqlite/statement.c b/Modules/_sqlite/statement.c index 57026270e1eeb5..358ee30074cb66 100644 --- a/Modules/_sqlite/statement.c +++ b/Modules/_sqlite/statement.c @@ -372,23 +372,36 @@ static void pysqlite_statement_dealloc(pysqlite_Statement *self) { PyTypeObject *tp = Py_TYPE(self); + PyObject_GC_UnTrack(self); if (self->st) { Py_BEGIN_ALLOW_THREADS sqlite3_finalize(self->st); Py_END_ALLOW_THREADS + self->st = NULL; } - self->st = NULL; - - Py_XDECREF(self->sql); + tp->tp_clear((PyObject *)self); + tp->tp_free(self); + Py_DECREF(tp); +} +static int +stmt_clear(pysqlite_Statement *self) +{ + Py_CLEAR(self->sql); if (self->in_weakreflist != NULL) { PyObject_ClearWeakRefs((PyObject*)self); } + return 0; +} - tp->tp_free(self); - Py_DECREF(tp); +static int +stmt_traverse(pysqlite_Statement *self, visitproc visit, void *arg) +{ + Py_VISIT(self->sql); + Py_VISIT(Py_TYPE(self)); + return 0; } /* @@ -468,14 +481,15 @@ static PyMemberDef stmt_members[] = { static PyType_Slot stmt_slots[] = { {Py_tp_members, stmt_members}, {Py_tp_dealloc, pysqlite_statement_dealloc}, - {Py_tp_new, PyType_GenericNew}, + {Py_tp_traverse, stmt_traverse}, + {Py_tp_clear, stmt_clear}, {0, NULL}, }; static PyType_Spec stmt_spec = { .name = MODULE_NAME ".Statement", .basicsize = sizeof(pysqlite_Statement), - .flags = Py_TPFLAGS_DEFAULT, + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, .slots = stmt_slots, }; PyTypeObject *pysqlite_StatementType = NULL; From ca870ac061d15c98b365279e8faec8b0cd8633cf Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 20 Jan 2021 22:13:12 +0100 Subject: [PATCH 06/14] sqlite3.Cache and sqlite3.Node types now implements GC protocol --- Modules/_sqlite/cache.c | 80 +++++++++++++++++++++++++++++------------ 1 file changed, 57 insertions(+), 23 deletions(-) diff --git a/Modules/_sqlite/cache.c b/Modules/_sqlite/cache.c index 8da0a64a3f90a4..9e811cc6c0279d 100644 --- a/Modules/_sqlite/cache.c +++ b/Modules/_sqlite/cache.c @@ -44,14 +44,27 @@ pysqlite_new_node(PyObject *key, PyObject *data) return node; } +static int +node_traverse(pysqlite_Node *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + return 0; +} + +static int +node_clear(pysqlite_Node *self) +{ + Py_CLEAR(self->key); + Py_CLEAR(self->data); + return 0; +} + static void pysqlite_node_dealloc(pysqlite_Node *self) { PyTypeObject *tp = Py_TYPE(self); - - Py_DECREF(self->key); - Py_DECREF(self->data); - + PyObject_GC_UnTrack(self); + tp->tp_clear((PyObject *)self); tp->tp_free(self); Py_DECREF(tp); } @@ -88,31 +101,50 @@ pysqlite_cache_init(pysqlite_Cache *self, PyObject *args, PyObject *kwargs) return 0; } -static void -pysqlite_cache_dealloc(pysqlite_Cache *self) +static int +cache_traverse(pysqlite_Cache *self, visitproc visit, void *arg) { - PyTypeObject *tp = Py_TYPE(self); - pysqlite_Node* node; - pysqlite_Node* delete_node; - - if (!self->factory) { - /* constructor failed, just get out of here */ - return; + pysqlite_Node *node = self->first; + while (node) { + Py_VISIT(node); + node = node->next; } + Py_VISIT(self->mapping); + if (self->decref_factory) { + Py_VISIT(self->factory); + } + Py_VISIT(Py_TYPE(self)); + return 0; +} +static int +cache_clear(pysqlite_Cache *self) +{ /* iterate over all nodes and deallocate them */ - node = self->first; + pysqlite_Node *node = self->first; while (node) { - delete_node = node; + pysqlite_Node *delete_node = node; node = node->next; - Py_DECREF(delete_node); + Py_CLEAR(delete_node); } - if (self->decref_factory) { - Py_DECREF(self->factory); + Py_CLEAR(self->factory); + } + Py_CLEAR(self->mapping); + return 0; +} + +static void +pysqlite_cache_dealloc(pysqlite_Cache *self) +{ + if (!self->factory) { + /* constructor failed, just get out of here */ + return; } - Py_DECREF(self->mapping); + PyObject_GC_UnTrack(self); + PyTypeObject *tp = Py_TYPE(self); + tp->tp_clear((PyObject *)self); tp->tp_free(self); Py_DECREF(tp); } @@ -260,14 +292,15 @@ pysqlite_cache_display(pysqlite_Cache *self, PyObject *args) static PyType_Slot node_slots[] = { {Py_tp_dealloc, pysqlite_node_dealloc}, - {Py_tp_new, PyType_GenericNew}, + {Py_tp_traverse, node_traverse}, + {Py_tp_clear, node_clear}, {0, NULL}, }; static PyType_Spec node_spec = { .name = MODULE_NAME ".Node", .basicsize = sizeof(pysqlite_Node), - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, .slots = node_slots, }; PyTypeObject *pysqlite_NodeType = NULL; @@ -283,15 +316,16 @@ static PyMethodDef cache_methods[] = { static PyType_Slot cache_slots[] = { {Py_tp_dealloc, pysqlite_cache_dealloc}, {Py_tp_methods, cache_methods}, - {Py_tp_new, PyType_GenericNew}, {Py_tp_init, pysqlite_cache_init}, + {Py_tp_traverse, cache_traverse}, + {Py_tp_clear, cache_clear}, {0, NULL}, }; static PyType_Spec cache_spec = { .name = MODULE_NAME ".Cache", .basicsize = sizeof(pysqlite_Cache), - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, .slots = cache_slots, }; PyTypeObject *pysqlite_CacheType = NULL; From f5d9873c22fb9608d5d1bf68dd1a027d6533829b Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Thu, 13 May 2021 22:13:45 +0200 Subject: [PATCH 07/14] Remove unneeded self->db = NULL --- Modules/_sqlite/connection.c | 1 - 1 file changed, 1 deletion(-) diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 0a3e55b6971818..f31342a8e8dcea 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -267,7 +267,6 @@ pysqlite_connection_dealloc(pysqlite_Connection *self) /* Clean up if user has not called .close() explicitly. */ if (self->db) { sqlite3_close_v2(self->db); - self->db = NULL; } tp->tp_free(self); From 34928edf7881738228751d70be95a51b8c62bfca Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Thu, 13 May 2021 22:15:42 +0200 Subject: [PATCH 08/14] Get rid of unneeded cast in cursor_dealloc --- Modules/_sqlite/cursor.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index f1d1c8a1bbcf7d..b3e1ce2c04784b 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -116,11 +116,11 @@ cursor_clear(pysqlite_Cursor *self) } static void -cursor_dealloc(pysqlite_Cursor *self) +cursor_dealloc(PyObject *self) { PyTypeObject *tp = Py_TYPE(self); PyObject_GC_UnTrack(self); - tp->tp_clear((PyObject *)self); + tp->tp_clear(self); tp->tp_free(self); Py_DECREF(tp); } From 590ff8ed081de39bd217a59dbf60d64e4a4c3ef4 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Sun, 23 May 2021 17:42:34 +0200 Subject: [PATCH 09/14] Address review: visit node->key, node->data, and con->isolation_level --- Modules/_sqlite/cache.c | 2 ++ Modules/_sqlite/connection.c | 1 + 2 files changed, 3 insertions(+) diff --git a/Modules/_sqlite/cache.c b/Modules/_sqlite/cache.c index 9e811cc6c0279d..6d2b178cb7379b 100644 --- a/Modules/_sqlite/cache.c +++ b/Modules/_sqlite/cache.c @@ -47,6 +47,8 @@ pysqlite_new_node(PyObject *key, PyObject *data) static int node_traverse(pysqlite_Node *self, visitproc visit, void *arg) { + Py_VISIT(self->key); + Py_VISIT(self->data); Py_VISIT(Py_TYPE(self)); return 0; } diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index f31342a8e8dcea..accc573e72b08c 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -229,6 +229,7 @@ static int connection_traverse(pysqlite_Connection *self, visitproc visit, void *arg) { Py_VISIT(self->statement_cache); + Py_VISIT(self->isolation_level); Py_VISIT(self->function_pinboard_trace_callback); Py_VISIT(self->function_pinboard_progress_handler); Py_VISIT(self->function_pinboard_authorizer_cb); From b080ff768ab4b5d76be3c182931dd8fec85b51fa Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 24 May 2021 09:07:51 +0200 Subject: [PATCH 10/14] Harden cache clear --- Modules/_sqlite/cache.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Modules/_sqlite/cache.c b/Modules/_sqlite/cache.c index 6d2b178cb7379b..e0a1707348c912 100644 --- a/Modules/_sqlite/cache.c +++ b/Modules/_sqlite/cache.c @@ -124,6 +124,7 @@ cache_clear(pysqlite_Cache *self) { /* iterate over all nodes and deallocate them */ pysqlite_Node *node = self->first; + self->first = NULL; while (node) { pysqlite_Node *delete_node = node; node = node->next; From 2bcfa293b2792e79ea4bd83e43f0875111c2fd86 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 24 May 2021 23:44:53 +0200 Subject: [PATCH 11/14] Normalize connection_dealloc naming --- Modules/_sqlite/connection.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index accc573e72b08c..47d97d17a91b98 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -259,7 +259,7 @@ connection_clear(pysqlite_Connection *self) } static void -pysqlite_connection_dealloc(pysqlite_Connection *self) +connection_dealloc(pysqlite_Connection *self) { PyTypeObject *tp = Py_TYPE(self); PyObject_GC_UnTrack(self); @@ -1932,7 +1932,7 @@ static struct PyMemberDef connection_members[] = }; static PyType_Slot connection_slots[] = { - {Py_tp_dealloc, pysqlite_connection_dealloc}, + {Py_tp_dealloc, connection_dealloc}, {Py_tp_doc, (void *)connection_doc}, {Py_tp_methods, connection_methods}, {Py_tp_members, connection_members}, From f8eb733c55de06f4c415dee0eecf2030a727d350 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 25 May 2021 08:36:44 +0200 Subject: [PATCH 12/14] Address review: visit row PyObjects for consistency --- Modules/_sqlite/row.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Modules/_sqlite/row.c b/Modules/_sqlite/row.c index d314c65370d34b..af8be803c805a5 100644 --- a/Modules/_sqlite/row.c +++ b/Modules/_sqlite/row.c @@ -42,6 +42,8 @@ row_clear(pysqlite_Row *self) static int row_traverse(pysqlite_Row *self, visitproc visit, void *arg) { + Py_VISIT(self->data); + Py_VISIT(self->description); Py_VISIT(Py_TYPE(self)); return 0; } From ab4c6e6903b16d84833de41aa8b5b774b7d562b5 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 25 May 2021 08:37:34 +0200 Subject: [PATCH 13/14] Normalize statement dealloc naming --- Modules/_sqlite/statement.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/_sqlite/statement.c b/Modules/_sqlite/statement.c index 358ee30074cb66..456342a7dfb944 100644 --- a/Modules/_sqlite/statement.c +++ b/Modules/_sqlite/statement.c @@ -369,7 +369,7 @@ void pysqlite_statement_mark_dirty(pysqlite_Statement* self) } static void -pysqlite_statement_dealloc(pysqlite_Statement *self) +stmt_dealloc(pysqlite_Statement *self) { PyTypeObject *tp = Py_TYPE(self); PyObject_GC_UnTrack(self); @@ -480,7 +480,7 @@ static PyMemberDef stmt_members[] = { }; static PyType_Slot stmt_slots[] = { {Py_tp_members, stmt_members}, - {Py_tp_dealloc, pysqlite_statement_dealloc}, + {Py_tp_dealloc, stmt_dealloc}, {Py_tp_traverse, stmt_traverse}, {Py_tp_clear, stmt_clear}, {0, NULL}, From 926787d930b978229e085437a081a6018d252ecc Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 25 May 2021 08:43:44 +0200 Subject: [PATCH 14/14] Clear sqlite3 stmt resources in stmt_clear() --- Modules/_sqlite/statement.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/Modules/_sqlite/statement.c b/Modules/_sqlite/statement.c index 456342a7dfb944..3be12c79b47d9a 100644 --- a/Modules/_sqlite/statement.c +++ b/Modules/_sqlite/statement.c @@ -373,14 +373,6 @@ stmt_dealloc(pysqlite_Statement *self) { PyTypeObject *tp = Py_TYPE(self); PyObject_GC_UnTrack(self); - - if (self->st) { - Py_BEGIN_ALLOW_THREADS - sqlite3_finalize(self->st); - Py_END_ALLOW_THREADS - self->st = NULL; - } - tp->tp_clear((PyObject *)self); tp->tp_free(self); Py_DECREF(tp); @@ -389,6 +381,13 @@ stmt_dealloc(pysqlite_Statement *self) static int stmt_clear(pysqlite_Statement *self) { + if (self->st) { + Py_BEGIN_ALLOW_THREADS + sqlite3_finalize(self->st); + Py_END_ALLOW_THREADS + self->st = 0; + } + Py_CLEAR(self->sql); if (self->in_weakreflist != NULL) { PyObject_ClearWeakRefs((PyObject*)self); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy