bpo-42064: Pass module state to trace, progress, and authorizer callbacks by erlend-aasland · Pull Request #27940 · python/cpython

Perhaps I was a little bit vague. I did the tests with an added implicit close in __init__.

diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c
index 63fd916662..961afe8de0 100644
--- a/Modules/_sqlite/connection.c
+++ b/Modules/_sqlite/connection.c
@@ -56,6 +56,7 @@ static const char * const begin_statements[] = {
 static int pysqlite_connection_set_isolation_level(pysqlite_Connection* self, PyObject* isolation_level, void *Py_UNUSED(ignored));
 static void _pysqlite_drop_unused_cursor_references(pysqlite_Connection* self);
 static void free_callback_context(callback_context *ctx);
+static void connection_close(pysqlite_Connection *self);
 
 static PyObject *
 new_statement_cache(pysqlite_Connection *self, int maxsize)
@@ -114,6 +115,18 @@ pysqlite_connection_init_impl(pysqlite_Connection *self,
         return -1;
     }
 
+    // Gracefully handle reinitialization
+    if (self->initialized) {
+        (void)sqlite3_set_authorizer(self->db, NULL, NULL);
+        sqlite3_progress_handler(self->db, 0, NULL, NULL);
+#ifdef HAVE_TRACE_V2
+        sqlite3_trace_v2(self->db, SQLITE_TRACE_STMT, NULL, NULL);
+#else
+        sqlite3_trace(self->db, NULL, NULL);
+#endif
+        connection_close(self);
+    }
+
     pysqlite_state *state = pysqlite_get_state_by_type(Py_TYPE(self));
     self->state = state;