[Python-checkins] bpo-42064: Move sqlite3 types to global state (GH-26537)

encukou webhook-mailer at python.org
Tue Jun 15 08:47:42 EDT 2021


https://github.com/python/cpython/commit/10a5c806d4dec6c342dcc9888fbe4fa1fa9b7a1f
commit: 10a5c806d4dec6c342dcc9888fbe4fa1fa9b7a1f
branch: main
author: Erlend Egeberg Aasland <erlend.aasland at innova.no>
committer: encukou <encukou at gmail.com>
date: 2021-06-15T14:47:34+02:00
summary:

bpo-42064: Move sqlite3 types to global state (GH-26537)

* Move connection type to global state
* Move cursor type to global state
* Move prepare protocol type to global state
* Move row type to global state
* Move statement type to global state
* ADD_TYPE takes a pointer
* pysqlite_get_state is now static inline

files:
M Modules/_sqlite/clinic/connection.c.h
M Modules/_sqlite/clinic/cursor.c.h
M Modules/_sqlite/clinic/module.c.h
M Modules/_sqlite/clinic/row.c.h
M Modules/_sqlite/connection.c
M Modules/_sqlite/cursor.c
M Modules/_sqlite/microprotocols.c
M Modules/_sqlite/module.c
M Modules/_sqlite/module.h
M Modules/_sqlite/prepare_protocol.c
M Modules/_sqlite/row.c
M Modules/_sqlite/statement.c

diff --git a/Modules/_sqlite/clinic/connection.c.h b/Modules/_sqlite/clinic/connection.c.h
index f231ecc2ae78be..41104e23dfdee2 100644
--- a/Modules/_sqlite/clinic/connection.c.h
+++ b/Modules/_sqlite/clinic/connection.c.h
@@ -552,8 +552,8 @@ pysqlite_connection_backup(pysqlite_Connection *self, PyObject *const *args, Py_
     if (!args) {
         goto exit;
     }
-    if (!PyObject_TypeCheck(args[0], pysqlite_ConnectionType)) {
-        _PyArg_BadArgument("backup", "argument 'target'", (pysqlite_ConnectionType)->tp_name, args[0]);
+    if (!PyObject_TypeCheck(args[0], clinic_state()->ConnectionType)) {
+        _PyArg_BadArgument("backup", "argument 'target'", (clinic_state()->ConnectionType)->tp_name, args[0]);
         goto exit;
     }
     target = (pysqlite_Connection *)args[0];
@@ -710,4 +710,4 @@ pysqlite_connection_exit(pysqlite_Connection *self, PyObject *const *args, Py_ss
 #ifndef PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF
     #define PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF
 #endif /* !defined(PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF) */
-/*[clinic end generated code: output=c1bf09db3bcd0105 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=1ee2f6173f4acec3 input=a9049054013a1b77]*/
diff --git a/Modules/_sqlite/clinic/cursor.c.h b/Modules/_sqlite/clinic/cursor.c.h
index 7a79d74818a2e2..b519094bf353fe 100644
--- a/Modules/_sqlite/clinic/cursor.c.h
+++ b/Modules/_sqlite/clinic/cursor.c.h
@@ -12,15 +12,15 @@ pysqlite_cursor_init(PyObject *self, PyObject *args, PyObject *kwargs)
     int return_value = -1;
     pysqlite_Connection *connection;
 
-    if (Py_IS_TYPE(self, pysqlite_CursorType) &&
+    if (Py_IS_TYPE(self, clinic_state()->CursorType) &&
         !_PyArg_NoKeywords("Cursor", kwargs)) {
         goto exit;
     }
     if (!_PyArg_CheckPositional("Cursor", PyTuple_GET_SIZE(args), 1, 1)) {
         goto exit;
     }
-    if (!PyObject_TypeCheck(PyTuple_GET_ITEM(args, 0), pysqlite_ConnectionType)) {
-        _PyArg_BadArgument("Cursor", "argument 1", (pysqlite_ConnectionType)->tp_name, PyTuple_GET_ITEM(args, 0));
+    if (!PyObject_TypeCheck(PyTuple_GET_ITEM(args, 0), clinic_state()->ConnectionType)) {
+        _PyArg_BadArgument("Cursor", "argument 1", (clinic_state()->ConnectionType)->tp_name, PyTuple_GET_ITEM(args, 0));
         goto exit;
     }
     connection = (pysqlite_Connection *)PyTuple_GET_ITEM(args, 0);
@@ -259,4 +259,4 @@ pysqlite_cursor_close(pysqlite_Cursor *self, PyObject *Py_UNUSED(ignored))
 {
     return pysqlite_cursor_close_impl(self);
 }
-/*[clinic end generated code: output=6a2d4d49784aa686 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=e3a502bb26aaefa5 input=a9049054013a1b77]*/
diff --git a/Modules/_sqlite/clinic/module.c.h b/Modules/_sqlite/clinic/module.c.h
index fb1e1187b209f8..18557355061fa8 100644
--- a/Modules/_sqlite/clinic/module.c.h
+++ b/Modules/_sqlite/clinic/module.c.h
@@ -198,7 +198,7 @@ pysqlite_adapt(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
 {
     PyObject *return_value = NULL;
     PyObject *obj;
-    PyObject *proto = (PyObject*)pysqlite_PrepareProtocolType;
+    PyObject *proto = (PyObject *)clinic_state()->PrepareProtocolType;
     PyObject *alt = NULL;
 
     if (!_PyArg_CheckPositional("adapt", nargs, 1, 3)) {
@@ -219,4 +219,4 @@ pysqlite_adapt(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
 exit:
     return return_value;
 }
-/*[clinic end generated code: output=d87990f941c209fa input=a9049054013a1b77]*/
+/*[clinic end generated code: output=e9c2442673289cab input=a9049054013a1b77]*/
diff --git a/Modules/_sqlite/clinic/row.c.h b/Modules/_sqlite/clinic/row.c.h
index 7ff110940d0b61..310d62b8a7f49a 100644
--- a/Modules/_sqlite/clinic/row.c.h
+++ b/Modules/_sqlite/clinic/row.c.h
@@ -13,15 +13,15 @@ pysqlite_row_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
     pysqlite_Cursor *cursor;
     PyObject *data;
 
-    if ((type == pysqlite_RowType) &&
+    if ((type == clinic_state()->RowType) &&
         !_PyArg_NoKeywords("Row", kwargs)) {
         goto exit;
     }
     if (!_PyArg_CheckPositional("Row", PyTuple_GET_SIZE(args), 2, 2)) {
         goto exit;
     }
-    if (!PyObject_TypeCheck(PyTuple_GET_ITEM(args, 0), pysqlite_CursorType)) {
-        _PyArg_BadArgument("Row", "argument 1", (pysqlite_CursorType)->tp_name, PyTuple_GET_ITEM(args, 0));
+    if (!PyObject_TypeCheck(PyTuple_GET_ITEM(args, 0), clinic_state()->CursorType)) {
+        _PyArg_BadArgument("Row", "argument 1", (clinic_state()->CursorType)->tp_name, PyTuple_GET_ITEM(args, 0));
         goto exit;
     }
     cursor = (pysqlite_Cursor *)PyTuple_GET_ITEM(args, 0);
@@ -53,4 +53,4 @@ pysqlite_row_keys(pysqlite_Row *self, PyObject *Py_UNUSED(ignored))
 {
     return pysqlite_row_keys_impl(self);
 }
-/*[clinic end generated code: output=8d29220b9cde035d input=a9049054013a1b77]*/
+/*[clinic end generated code: output=0382771b4fc85f36 input=a9049054013a1b77]*/
diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c
index 9199c347caab0d..915515c0a195a1 100644
--- a/Modules/_sqlite/connection.c
+++ b/Modules/_sqlite/connection.c
@@ -36,12 +36,15 @@
 #define HAVE_TRACE_V2
 #endif
 
+#define clinic_state() (pysqlite_get_state(NULL))
 #include "clinic/connection.c.h"
+#undef clinic_state
+
 /*[clinic input]
 module _sqlite3
-class _sqlite3.Connection "pysqlite_Connection *" "pysqlite_ConnectionType"
+class _sqlite3.Connection "pysqlite_Connection *" "clinic_state()->ConnectionType"
 [clinic start generated code]*/
-/*[clinic end generated code: output=da39a3ee5e6b4b0d input=aa796073bd8f69db]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=67369db2faf80891]*/
 
 _Py_IDENTIFIER(cursor);
 
@@ -339,14 +342,15 @@ pysqlite_connection_cursor_impl(pysqlite_Connection *self, PyObject *factory)
         return NULL;
     }
 
+    pysqlite_state *state = pysqlite_get_state(NULL);
     if (factory == NULL) {
-        factory = (PyObject*)pysqlite_CursorType;
+        factory = (PyObject *)state->CursorType;
     }
 
     cursor = PyObject_CallOneArg(factory, (PyObject *)self);
     if (cursor == NULL)
         return NULL;
-    if (!PyObject_TypeCheck(cursor, pysqlite_CursorType)) {
+    if (!PyObject_TypeCheck(cursor, state->CursorType)) {
         PyErr_Format(PyExc_TypeError,
                      "factory must return a cursor, not %.100s",
                      Py_TYPE(cursor)->tp_name);
@@ -1592,7 +1596,7 @@ pysqlite_connection_iterdump_impl(pysqlite_Connection *self)
 /*[clinic input]
 _sqlite3.Connection.backup as pysqlite_connection_backup
 
-    target: object(type='pysqlite_Connection *', subclass_of='pysqlite_ConnectionType')
+    target: object(type='pysqlite_Connection *', subclass_of='clinic_state()->ConnectionType')
     *
     pages: int = -1
     progress: object = None
@@ -1607,7 +1611,7 @@ pysqlite_connection_backup_impl(pysqlite_Connection *self,
                                 pysqlite_Connection *target, int pages,
                                 PyObject *progress, const char *name,
                                 double sleep)
-/*[clinic end generated code: output=306a3e6a38c36334 input=30ae45fc420bfd3b]*/
+/*[clinic end generated code: output=306a3e6a38c36334 input=c759627ab1ad46ff]*/
 {
     int rc;
     int sleep_ms = (int)(sleep * 1000.0);
@@ -1914,14 +1918,14 @@ static PyType_Spec connection_spec = {
     .slots = connection_slots,
 };
 
-PyTypeObject *pysqlite_ConnectionType = NULL;
-
 int
 pysqlite_connection_setup_types(PyObject *module)
 {
-    pysqlite_ConnectionType = (PyTypeObject *)PyType_FromModuleAndSpec(module, &connection_spec, NULL);
-    if (pysqlite_ConnectionType == NULL) {
+    PyObject *type = PyType_FromModuleAndSpec(module, &connection_spec, NULL);
+    if (type == NULL) {
         return -1;
     }
+    pysqlite_state *state = pysqlite_get_state(module);
+    state->ConnectionType = (PyTypeObject *)type;
     return 0;
 }
diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c
index c2e8de5b6c0f00..8c8a347f46e57a 100644
--- a/Modules/_sqlite/cursor.c
+++ b/Modules/_sqlite/cursor.c
@@ -24,20 +24,23 @@
 #include "cursor.h"
 #include "module.h"
 #include "util.h"
+
+#define clinic_state() (pysqlite_get_state(NULL))
 #include "clinic/cursor.c.h"
+#undef clinic_state
 
 /*[clinic input]
 module _sqlite3
-class _sqlite3.Cursor "pysqlite_Cursor *" "pysqlite_CursorType"
+class _sqlite3.Cursor "pysqlite_Cursor *" "clinic_state()->CursorType"
 [clinic start generated code]*/
-/*[clinic end generated code: output=da39a3ee5e6b4b0d input=b2072d8db95411d5]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3c5b8115c5cf30f1]*/
 
 static const char errmsg_fetch_across_rollback[] = "Cursor needed to be reset because of commit/rollback and can no longer be fetched from.";
 
 /*[clinic input]
 _sqlite3.Cursor.__init__ as pysqlite_cursor_init
 
-    connection: object(type='pysqlite_Connection *', subclass_of='pysqlite_ConnectionType')
+    connection: object(type='pysqlite_Connection *', subclass_of='clinic_state()->ConnectionType')
     /
 
 [clinic start generated code]*/
@@ -45,7 +48,7 @@ _sqlite3.Cursor.__init__ as pysqlite_cursor_init
 static int
 pysqlite_cursor_init_impl(pysqlite_Cursor *self,
                           pysqlite_Connection *connection)
-/*[clinic end generated code: output=ac59dce49a809ca8 input=a8a4f75ac90999b2]*/
+/*[clinic end generated code: output=ac59dce49a809ca8 input=23d4265b534989fb]*/
 {
     Py_INCREF(connection);
     Py_XSETREF(self->connection, connection);
@@ -1079,14 +1082,14 @@ static PyType_Spec cursor_spec = {
     .slots = cursor_slots,
 };
 
-PyTypeObject *pysqlite_CursorType = NULL;
-
 int
 pysqlite_cursor_setup_types(PyObject *module)
 {
-    pysqlite_CursorType = (PyTypeObject *)PyType_FromModuleAndSpec(module, &cursor_spec, NULL);
-    if (pysqlite_CursorType == NULL) {
+    PyObject *type = PyType_FromModuleAndSpec(module, &cursor_spec, NULL);
+    if (type == NULL) {
         return -1;
     }
+    pysqlite_state *state = pysqlite_get_state(module);
+    state->CursorType = (PyTypeObject *)type;
     return 0;
 }
diff --git a/Modules/_sqlite/microprotocols.c b/Modules/_sqlite/microprotocols.c
index e219a7239f8a7d..b2d6e7c427031f 100644
--- a/Modules/_sqlite/microprotocols.c
+++ b/Modules/_sqlite/microprotocols.c
@@ -58,8 +58,8 @@ pysqlite_microprotocols_add(PyTypeObject *type, PyObject *proto, PyObject *cast)
     PyObject* key;
     int rc;
 
-    if (proto == NULL) proto = (PyObject*)pysqlite_PrepareProtocolType;
-
+    assert(type != NULL);
+    assert(proto != NULL);
     key = Py_BuildValue("(OO)", (PyObject*)type, proto);
     if (!key) {
         return -1;
@@ -81,7 +81,7 @@ pysqlite_microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt)
     PyObject *adapter, *key, *adapted;
 
     /* we don't check for exact type conformance as specified in PEP 246
-       because the pysqlite_PrepareProtocolType type is abstract and there is no
+       because the PrepareProtocolType type is abstract and there is no
        way to get a quotable object to be its instance */
 
     /* look for an adapter in the registry */
diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c
index c60007e2059536..9587cbd4b9971c 100644
--- a/Modules/_sqlite/module.c
+++ b/Modules/_sqlite/module.c
@@ -32,7 +32,10 @@
 #error "SQLite 3.7.15 or higher required"
 #endif
 
+#define clinic_state() (pysqlite_get_state(NULL))
 #include "clinic/module.c.h"
+#undef clinic_state
+
 /*[clinic input]
 module _sqlite3
 [clinic start generated code]*/
@@ -57,12 +60,6 @@ int pysqlite_BaseTypeAdapted = 0;
 
 pysqlite_state pysqlite_global_state;
 
-pysqlite_state *
-pysqlite_get_state(PyObject *Py_UNUSED(module))
-{
-    return &pysqlite_global_state;
-}
-
 static PyObject* module_connect(PyObject* self, PyObject* args, PyObject*
         kwargs)
 {
@@ -93,7 +90,8 @@ static PyObject* module_connect(PyObject* self, PyObject* args, PyObject*
     }
 
     if (factory == NULL) {
-        factory = (PyObject*)pysqlite_ConnectionType;
+        pysqlite_state *state = pysqlite_get_state(self);
+        factory = (PyObject *)state->ConnectionType;
     }
 
     return PyObject_Call(factory, args, kwargs);
@@ -176,9 +174,12 @@ pysqlite_register_adapter_impl(PyObject *module, PyTypeObject *type,
         pysqlite_BaseTypeAdapted = 1;
     }
 
-    rc = pysqlite_microprotocols_add(type, (PyObject*)pysqlite_PrepareProtocolType, caster);
-    if (rc == -1)
+    pysqlite_state *state = pysqlite_get_state(NULL);
+    PyObject *protocol = (PyObject *)state->PrepareProtocolType;
+    rc = pysqlite_microprotocols_add(type, protocol, caster);
+    if (rc == -1) {
         return NULL;
+    }
 
     Py_RETURN_NONE;
 }
@@ -240,7 +241,7 @@ pysqlite_enable_callback_trace_impl(PyObject *module, int enable)
 _sqlite3.adapt as pysqlite_adapt
 
     obj: object
-    proto: object(c_default='(PyObject*)pysqlite_PrepareProtocolType') = PrepareProtocolType
+    proto: object(c_default='(PyObject *)clinic_state()->PrepareProtocolType') = PrepareProtocolType
     alt: object = NULL
     /
 
@@ -250,7 +251,7 @@ Adapt given object to given protocol. Non-standard.
 static PyObject *
 pysqlite_adapt_impl(PyObject *module, PyObject *obj, PyObject *proto,
                     PyObject *alt)
-/*[clinic end generated code: output=0c3927c5fcd23dd9 input=a58ab77fb5ae22dd]*/
+/*[clinic end generated code: output=0c3927c5fcd23dd9 input=c8995aeb25d0e542]*/
 {
     return pysqlite_microprotocols_adapt(obj, proto, alt);
 }
@@ -358,7 +359,7 @@ static struct PyModuleDef _sqlite3module = {
 
 #define ADD_TYPE(module, type)                 \
 do {                                           \
-    if (PyModule_AddType(module, &type) < 0) { \
+    if (PyModule_AddType(module, type) < 0) {  \
         goto error;                            \
     }                                          \
 } while (0)
@@ -392,6 +393,7 @@ PyMODINIT_FUNC PyInit__sqlite3(void)
     }
 
     module = PyModule_Create(&_sqlite3module);
+    pysqlite_state *state = pysqlite_get_state(module);
 
     if (!module ||
         (pysqlite_row_setup_types(module) < 0) ||
@@ -403,10 +405,10 @@ PyMODINIT_FUNC PyInit__sqlite3(void)
         goto error;
     }
 
-    ADD_TYPE(module, *pysqlite_ConnectionType);
-    ADD_TYPE(module, *pysqlite_CursorType);
-    ADD_TYPE(module, *pysqlite_PrepareProtocolType);
-    ADD_TYPE(module, *pysqlite_RowType);
+    ADD_TYPE(module, state->ConnectionType);
+    ADD_TYPE(module, state->CursorType);
+    ADD_TYPE(module, state->PrepareProtocolType);
+    ADD_TYPE(module, state->RowType);
 
     /*** Create DB-API Exception hierarchy */
     ADD_EXCEPTION(module, "Error", pysqlite_Error, PyExc_Exception);
diff --git a/Modules/_sqlite/module.h b/Modules/_sqlite/module.h
index a40e86e9c4da72..3f29035b5fe68a 100644
--- a/Modules/_sqlite/module.h
+++ b/Modules/_sqlite/module.h
@@ -31,9 +31,20 @@
 
 typedef struct {
     PyObject *lru_cache;
+    PyTypeObject *ConnectionType;
+    PyTypeObject *CursorType;
+    PyTypeObject *PrepareProtocolType;
+    PyTypeObject *RowType;
+    PyTypeObject *StatementType;
 } pysqlite_state;
 
-extern pysqlite_state *pysqlite_get_state(PyObject *module);
+extern pysqlite_state pysqlite_global_state;
+
+static inline pysqlite_state *
+pysqlite_get_state(PyObject *Py_UNUSED(module))
+{
+    return &pysqlite_global_state;
+}
 
 extern PyObject* pysqlite_Error;
 extern PyObject* pysqlite_Warning;
diff --git a/Modules/_sqlite/prepare_protocol.c b/Modules/_sqlite/prepare_protocol.c
index ece42f4df6f5ac..1f9d7b751d209b 100644
--- a/Modules/_sqlite/prepare_protocol.c
+++ b/Modules/_sqlite/prepare_protocol.c
@@ -60,14 +60,14 @@ static PyType_Spec type_spec = {
     .slots = type_slots,
 };
 
-PyTypeObject *pysqlite_PrepareProtocolType = NULL;
-
 int
 pysqlite_prepare_protocol_setup_types(PyObject *module)
 {
-    pysqlite_PrepareProtocolType = (PyTypeObject *)PyType_FromModuleAndSpec(module, &type_spec, NULL);
-    if (pysqlite_PrepareProtocolType == NULL) {
+    PyObject *type = PyType_FromModuleAndSpec(module, &type_spec, NULL);
+    if (type == NULL) {
         return -1;
     }
+    pysqlite_state *state = pysqlite_get_state(module);
+    state->PrepareProtocolType = (PyTypeObject *)type;
     return 0;
 }
diff --git a/Modules/_sqlite/row.c b/Modules/_sqlite/row.c
index 24722be49082cf..bf43dad4473aae 100644
--- a/Modules/_sqlite/row.c
+++ b/Modules/_sqlite/row.c
@@ -23,13 +23,16 @@
 
 #include "row.h"
 #include "cursor.h"
+
+#define clinic_state() (pysqlite_get_state(NULL))
 #include "clinic/row.c.h"
+#undef clinic_state
 
 /*[clinic input]
 module _sqlite3
-class _sqlite3.Row "pysqlite_Row *" "pysqlite_RowType"
+class _sqlite3.Row "pysqlite_Row *" "clinic_state()->RowType"
 [clinic start generated code]*/
-/*[clinic end generated code: output=da39a3ee5e6b4b0d input=384227da65f250fd]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=966c53403d7f3a40]*/
 
 static int
 row_clear(pysqlite_Row *self)
@@ -62,7 +65,7 @@ pysqlite_row_dealloc(PyObject *self)
 @classmethod
 _sqlite3.Row.__new__ as pysqlite_row_new
 
-    cursor: object(type='pysqlite_Cursor *', subclass_of='pysqlite_CursorType')
+    cursor: object(type='pysqlite_Cursor *', subclass_of='clinic_state()->CursorType')
     data: object(subclass_of='&PyTuple_Type')
     /
 
@@ -71,7 +74,7 @@ _sqlite3.Row.__new__ as pysqlite_row_new
 static PyObject *
 pysqlite_row_new_impl(PyTypeObject *type, pysqlite_Cursor *cursor,
                       PyObject *data)
-/*[clinic end generated code: output=10d58b09a819a4c1 input=f6cd7e6e0935828d]*/
+/*[clinic end generated code: output=10d58b09a819a4c1 input=b9e954ca31345dbf]*/
 {
     pysqlite_Row *self;
 
@@ -216,7 +219,8 @@ static PyObject* pysqlite_row_richcompare(pysqlite_Row *self, PyObject *_other,
     if (opid != Py_EQ && opid != Py_NE)
         Py_RETURN_NOTIMPLEMENTED;
 
-    if (PyObject_TypeCheck(_other, pysqlite_RowType)) {
+    pysqlite_state *state = pysqlite_get_state(NULL);
+    if (PyObject_TypeCheck(_other, state->RowType)) {
         pysqlite_Row *other = (pysqlite_Row *)_other;
         int eq = PyObject_RichCompareBool(self->description, other->description, Py_EQ);
         if (eq < 0) {
@@ -258,14 +262,14 @@ static PyType_Spec row_spec = {
     .slots = row_slots,
 };
 
-PyTypeObject *pysqlite_RowType = NULL;
-
 int
 pysqlite_row_setup_types(PyObject *module)
 {
-    pysqlite_RowType = (PyTypeObject *)PyType_FromModuleAndSpec(module, &row_spec, NULL);
-    if (pysqlite_RowType == NULL) {
+    PyObject *type = PyType_FromModuleAndSpec(module, &row_spec, NULL);
+    if (type == NULL) {
         return -1;
     }
+    pysqlite_state *state = pysqlite_get_state(module);
+    state->RowType = (PyTypeObject *)type;
     return 0;
 }
diff --git a/Modules/_sqlite/statement.c b/Modules/_sqlite/statement.c
index eca225820cd75e..89fe4bbec3ea43 100644
--- a/Modules/_sqlite/statement.c
+++ b/Modules/_sqlite/statement.c
@@ -110,8 +110,9 @@ pysqlite_statement_create(pysqlite_Connection *connection, PyObject *sql)
         break;
     }
 
+    pysqlite_state *state = pysqlite_get_state(NULL);
     pysqlite_Statement *self = PyObject_GC_New(pysqlite_Statement,
-                                               pysqlite_StatementType);
+                                               state->StatementType);
     if (self == NULL) {
         goto error;
     }
@@ -223,6 +224,7 @@ static int _need_adapt(PyObject* obj)
 
 void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* parameters)
 {
+    pysqlite_state *state = pysqlite_get_state(NULL);
     PyObject* current_param;
     PyObject* adapted;
     const char* binding_name;
@@ -271,7 +273,10 @@ void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* para
             if (!_need_adapt(current_param)) {
                 adapted = current_param;
             } else {
-                adapted = pysqlite_microprotocols_adapt(current_param, (PyObject*)pysqlite_PrepareProtocolType, current_param);
+                PyObject *protocol = (PyObject *)state->PrepareProtocolType;
+                adapted = pysqlite_microprotocols_adapt(current_param,
+                                                        protocol,
+                                                        current_param);
                 Py_DECREF(current_param);
                 if (!adapted) {
                     return;
@@ -322,7 +327,10 @@ void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* para
             if (!_need_adapt(current_param)) {
                 adapted = current_param;
             } else {
-                adapted = pysqlite_microprotocols_adapt(current_param, (PyObject*)pysqlite_PrepareProtocolType, current_param);
+                PyObject *protocol = (PyObject *)state->PrepareProtocolType;
+                adapted = pysqlite_microprotocols_adapt(current_param,
+                                                        protocol,
+                                                        current_param);
                 Py_DECREF(current_param);
                 if (!adapted) {
                     return;
@@ -497,14 +505,15 @@ static PyType_Spec stmt_spec = {
     .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
     .slots = stmt_slots,
 };
-PyTypeObject *pysqlite_StatementType = NULL;
 
 int
 pysqlite_statement_setup_types(PyObject *module)
 {
-    pysqlite_StatementType = (PyTypeObject *)PyType_FromModuleAndSpec(module, &stmt_spec, NULL);
-    if (pysqlite_StatementType == NULL) {
+    PyObject *type = PyType_FromModuleAndSpec(module, &stmt_spec, NULL);
+    if (type == NULL) {
         return -1;
     }
+    pysqlite_state *state = pysqlite_get_state(module);
+    state->StatementType = (PyTypeObject *)type;
     return 0;
 }



More information about the Python-checkins mailing list