From 99cdaff3a9b3142b22ad428287595bf7c06fbf3c Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 19 Oct 2021 18:06:32 +0200 Subject: [PATCH 1/4] bpo-42064: Convert global state to module state --- Modules/_sqlite/clinic/connection.c.h | 21 ++++++++++++++++----- Modules/_sqlite/connection.c | 10 ++++++---- Modules/_sqlite/cursor.c | 2 +- Modules/_sqlite/microprotocols.c | 4 ++-- Modules/_sqlite/microprotocols.h | 5 +++-- Modules/_sqlite/module.c | 21 +++++++-------------- Modules/_sqlite/module.h | 20 +++++++++++++------- Modules/_sqlite/row.c | 2 +- 8 files changed, 49 insertions(+), 36 deletions(-) diff --git a/Modules/_sqlite/clinic/connection.c.h b/Modules/_sqlite/clinic/connection.c.h index e9e3064ae0f899..876a200a7a16ea 100644 --- a/Modules/_sqlite/clinic/connection.c.h +++ b/Modules/_sqlite/clinic/connection.c.h @@ -150,15 +150,26 @@ PyDoc_STRVAR(pysqlite_connection_close__doc__, "Closes the connection."); #define PYSQLITE_CONNECTION_CLOSE_METHODDEF \ - {"close", (PyCFunction)pysqlite_connection_close, METH_NOARGS, pysqlite_connection_close__doc__}, + {"close", (PyCFunction)(void(*)(void))pysqlite_connection_close, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_close__doc__}, static PyObject * -pysqlite_connection_close_impl(pysqlite_Connection *self); +pysqlite_connection_close_impl(pysqlite_Connection *self, PyTypeObject *cls); static PyObject * -pysqlite_connection_close(pysqlite_Connection *self, PyObject *Py_UNUSED(ignored)) +pysqlite_connection_close(pysqlite_Connection *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return pysqlite_connection_close_impl(self); + PyObject *return_value = NULL; + static const char * const _keywords[] = { NULL}; + static _PyArg_Parser _parser = {":close", _keywords, 0}; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser + )) { + goto exit; + } + return_value = pysqlite_connection_close_impl(self, cls); + +exit: + return return_value; } PyDoc_STRVAR(pysqlite_connection_commit__doc__, @@ -757,4 +768,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=7567e5d716309258 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2cd6449f4a8f9a2a input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index e94c4cbb4e8c3a..63e61b61840b13 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -59,7 +59,7 @@ clinic_fsconverter(PyObject *pathlike, const char **result) return 0; } -#define clinic_state() (pysqlite_get_state(NULL)) +#define clinic_state() (pysqlite_get_state_by_type(Py_TYPE(self))) #include "clinic/connection.c.h" #undef clinic_state @@ -404,19 +404,21 @@ pysqlite_connection_cursor_impl(pysqlite_Connection *self, PyObject *factory) /*[clinic input] _sqlite3.Connection.close as pysqlite_connection_close + cls: defining_class + Closes the connection. [clinic start generated code]*/ static PyObject * -pysqlite_connection_close_impl(pysqlite_Connection *self) -/*[clinic end generated code: output=a546a0da212c9b97 input=3d58064bbffaa3d3]*/ +pysqlite_connection_close_impl(pysqlite_Connection *self, PyTypeObject *cls) +/*[clinic end generated code: output=981f0a726752b78a input=16141a7506e49f33]*/ { if (!pysqlite_check_thread(self)) { return NULL; } if (!self->initialized) { - pysqlite_state *state = pysqlite_get_state(NULL); + pysqlite_state *state = pysqlite_get_state_by_cls(cls); PyErr_SetString(state->ProgrammingError, "Base Connection.__init__ not called."); return NULL; diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index ca74a68de4dba7..4b1ca00dfa38a2 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -25,7 +25,7 @@ #include "module.h" #include "util.h" -#define clinic_state() (pysqlite_get_state(NULL)) +#define clinic_state() (pysqlite_get_state_by_type(Py_TYPE(self))) #include "clinic/cursor.c.h" #undef clinic_state diff --git a/Modules/_sqlite/microprotocols.c b/Modules/_sqlite/microprotocols.c index 68e4f7fb166db7..95c799d306f308 100644 --- a/Modules/_sqlite/microprotocols.c +++ b/Modules/_sqlite/microprotocols.c @@ -49,7 +49,8 @@ pysqlite_microprotocols_init(PyObject *module) /* pysqlite_microprotocols_add - add a reverse type-caster to the dictionary */ int -pysqlite_microprotocols_add(PyTypeObject *type, PyObject *proto, PyObject *cast) +pysqlite_microprotocols_add(pysqlite_state *state, PyTypeObject *type, + PyObject *proto, PyObject *cast) { PyObject* key; int rc; @@ -61,7 +62,6 @@ pysqlite_microprotocols_add(PyTypeObject *type, PyObject *proto, PyObject *cast) return -1; } - pysqlite_state *state = pysqlite_get_state(NULL); rc = PyDict_SetItem(state->psyco_adapters, key, cast); Py_DECREF(key); diff --git a/Modules/_sqlite/microprotocols.h b/Modules/_sqlite/microprotocols.h index d12bc448596c4b..6bde9d01f45299 100644 --- a/Modules/_sqlite/microprotocols.h +++ b/Modules/_sqlite/microprotocols.h @@ -33,8 +33,9 @@ /* used by module.c to init the microprotocols system */ extern int pysqlite_microprotocols_init(PyObject *module); -extern int pysqlite_microprotocols_add( - PyTypeObject *type, PyObject *proto, PyObject *cast); +extern int pysqlite_microprotocols_add(pysqlite_state *state, + PyTypeObject *type, PyObject *proto, + PyObject *cast); extern PyObject *pysqlite_microprotocols_adapt(pysqlite_state *state, PyObject *obj, PyObject *proto, PyObject *alt); diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c index 47b1f7a9d0720c..e41ac0fc1ab733 100644 --- a/Modules/_sqlite/module.c +++ b/Modules/_sqlite/module.c @@ -32,7 +32,7 @@ #error "SQLite 3.7.15 or higher required" #endif -#define clinic_state() (pysqlite_get_state(NULL)) +#define clinic_state() (pysqlite_get_state(module)) #include "clinic/module.c.h" #undef clinic_state @@ -41,8 +41,6 @@ module _sqlite3 [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=81e330492d57488e]*/ -pysqlite_state pysqlite_global_state; - // NOTE: This must equal sqlite3.Connection.__init__ argument spec! /*[clinic input] _sqlite3.connect as pysqlite_connect @@ -160,7 +158,7 @@ pysqlite_register_adapter_impl(PyObject *module, PyTypeObject *type, pysqlite_state *state = pysqlite_get_state(module); PyObject *protocol = (PyObject *)state->PrepareProtocolType; - rc = pysqlite_microprotocols_add(type, protocol, caster); + rc = pysqlite_microprotocols_add(state, type, protocol, caster); if (rc == -1) { return NULL; } @@ -395,16 +393,11 @@ static int add_integer_constants(PyObject *module) { return ret; } -static struct PyModuleDef _sqlite3module = { - PyModuleDef_HEAD_INIT, - "_sqlite3", - NULL, - -1, - module_methods, - NULL, - NULL, - NULL, - NULL +struct PyModuleDef _sqlite3module = { + .m_base = PyModuleDef_HEAD_INIT, + .m_name = "_sqlite3", + .m_size = sizeof(pysqlite_state), + .m_methods = module_methods, }; #define ADD_TYPE(module, type) \ diff --git a/Modules/_sqlite/module.h b/Modules/_sqlite/module.h index c273c1f9ed9f29..9cba90e9353e8c 100644 --- a/Modules/_sqlite/module.h +++ b/Modules/_sqlite/module.h @@ -63,22 +63,28 @@ typedef struct { extern pysqlite_state pysqlite_global_state; static inline pysqlite_state * -pysqlite_get_state(PyObject *Py_UNUSED(module)) +pysqlite_get_state(PyObject *module) { - return &pysqlite_global_state; // Replace with PyModule_GetState + pysqlite_state *state = (pysqlite_state *)PyModule_GetState(module); + assert(state != NULL); + return state; } static inline pysqlite_state * -pysqlite_get_state_by_cls(PyTypeObject *Py_UNUSED(cls)) +pysqlite_get_state_by_cls(PyTypeObject *cls) { - return &pysqlite_global_state; // Replace with PyType_GetModuleState + pysqlite_state *state = (pysqlite_state *)PyType_GetModuleState(cls); + assert(state != NULL); + return state; } +struct PyModuleDef _sqlite3module; static inline pysqlite_state * -pysqlite_get_state_by_type(PyTypeObject *Py_UNUSED(tp)) +pysqlite_get_state_by_type(PyTypeObject *tp) { - // Replace with _PyType_GetModuleByDef & PyModule_GetState - return &pysqlite_global_state; + PyObject *module = _PyType_GetModuleByDef(tp, &_sqlite3module); + assert(module != NULL); + return pysqlite_get_state(module); } extern const char *pysqlite_error_name(int rc); diff --git a/Modules/_sqlite/row.c b/Modules/_sqlite/row.c index b146c9dc5e3bd1..c7830e8d08e740 100644 --- a/Modules/_sqlite/row.c +++ b/Modules/_sqlite/row.c @@ -24,7 +24,7 @@ #include "row.h" #include "cursor.h" -#define clinic_state() (pysqlite_get_state(NULL)) +#define clinic_state() (pysqlite_get_state_by_type(type)) #include "clinic/row.c.h" #undef clinic_state From ebae5a8c0f6844bf58f6c0b640ffcd823ea8cf64 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 20 Oct 2021 19:40:44 +0200 Subject: [PATCH 2/4] Address review: fix module state in Row tp_richcompare --- Modules/_sqlite/row.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/_sqlite/row.c b/Modules/_sqlite/row.c index c7830e8d08e740..1a1943285ce008 100644 --- a/Modules/_sqlite/row.c +++ b/Modules/_sqlite/row.c @@ -219,7 +219,7 @@ static PyObject* pysqlite_row_richcompare(pysqlite_Row *self, PyObject *_other, if (opid != Py_EQ && opid != Py_NE) Py_RETURN_NOTIMPLEMENTED; - pysqlite_state *state = pysqlite_get_state_by_cls(Py_TYPE(self)); + pysqlite_state *state = pysqlite_get_state_by_type(Py_TYPE(self)); if (PyObject_TypeCheck(_other, state->RowType)) { pysqlite_Row *other = (pysqlite_Row *)_other; int eq = PyObject_RichCompareBool(self->description, other->description, Py_EQ); From 7ac66b6e68ac616b500630c46c6b2c32153a4b07 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 20 Oct 2021 19:44:54 +0200 Subject: [PATCH 3/4] Address review: drop pysqlite_get_state_by_cls in favour of pysqlite_get_state_by_type --- Modules/_sqlite/clinic/connection.c.h | 21 +++++---------------- Modules/_sqlite/clinic/cursor.c.h | 21 +++++---------------- Modules/_sqlite/connection.c | 9 ++++----- Modules/_sqlite/cursor.c | 9 ++++----- Modules/_sqlite/module.h | 8 -------- 5 files changed, 18 insertions(+), 50 deletions(-) diff --git a/Modules/_sqlite/clinic/connection.c.h b/Modules/_sqlite/clinic/connection.c.h index 876a200a7a16ea..e9e3064ae0f899 100644 --- a/Modules/_sqlite/clinic/connection.c.h +++ b/Modules/_sqlite/clinic/connection.c.h @@ -150,26 +150,15 @@ PyDoc_STRVAR(pysqlite_connection_close__doc__, "Closes the connection."); #define PYSQLITE_CONNECTION_CLOSE_METHODDEF \ - {"close", (PyCFunction)(void(*)(void))pysqlite_connection_close, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_close__doc__}, + {"close", (PyCFunction)pysqlite_connection_close, METH_NOARGS, pysqlite_connection_close__doc__}, static PyObject * -pysqlite_connection_close_impl(pysqlite_Connection *self, PyTypeObject *cls); +pysqlite_connection_close_impl(pysqlite_Connection *self); static PyObject * -pysqlite_connection_close(pysqlite_Connection *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +pysqlite_connection_close(pysqlite_Connection *self, PyObject *Py_UNUSED(ignored)) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":close", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; - } - return_value = pysqlite_connection_close_impl(self, cls); - -exit: - return return_value; + return pysqlite_connection_close_impl(self); } PyDoc_STRVAR(pysqlite_connection_commit__doc__, @@ -768,4 +757,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=2cd6449f4a8f9a2a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7567e5d716309258 input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/clinic/cursor.c.h b/Modules/_sqlite/clinic/cursor.c.h index eb3e7ce31ada30..d8a36ac38aaf05 100644 --- a/Modules/_sqlite/clinic/cursor.c.h +++ b/Modules/_sqlite/clinic/cursor.c.h @@ -279,25 +279,14 @@ PyDoc_STRVAR(pysqlite_cursor_close__doc__, "Closes the cursor."); #define PYSQLITE_CURSOR_CLOSE_METHODDEF \ - {"close", (PyCFunction)(void(*)(void))pysqlite_cursor_close, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, pysqlite_cursor_close__doc__}, + {"close", (PyCFunction)pysqlite_cursor_close, METH_NOARGS, pysqlite_cursor_close__doc__}, static PyObject * -pysqlite_cursor_close_impl(pysqlite_Cursor *self, PyTypeObject *cls); +pysqlite_cursor_close_impl(pysqlite_Cursor *self); static PyObject * -pysqlite_cursor_close(pysqlite_Cursor *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +pysqlite_cursor_close(pysqlite_Cursor *self, PyObject *Py_UNUSED(ignored)) { - PyObject *return_value = NULL; - static const char * const _keywords[] = { NULL}; - static _PyArg_Parser _parser = {":close", _keywords, 0}; - - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser - )) { - goto exit; - } - return_value = pysqlite_cursor_close_impl(self, cls); - -exit: - return return_value; + return pysqlite_cursor_close_impl(self); } -/*[clinic end generated code: output=3b5328c1619b7626 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=514f6eb4e4974671 input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 63e61b61840b13..da2f12e8f99c2a 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -404,21 +404,20 @@ pysqlite_connection_cursor_impl(pysqlite_Connection *self, PyObject *factory) /*[clinic input] _sqlite3.Connection.close as pysqlite_connection_close - cls: defining_class - Closes the connection. [clinic start generated code]*/ static PyObject * -pysqlite_connection_close_impl(pysqlite_Connection *self, PyTypeObject *cls) -/*[clinic end generated code: output=981f0a726752b78a input=16141a7506e49f33]*/ +pysqlite_connection_close_impl(pysqlite_Connection *self) +/*[clinic end generated code: output=a546a0da212c9b97 input=3d58064bbffaa3d3]*/ { if (!pysqlite_check_thread(self)) { return NULL; } if (!self->initialized) { - pysqlite_state *state = pysqlite_get_state_by_cls(cls); + PyTypeObject *tp = Py_TYPE(self); + pysqlite_state *state = pysqlite_get_state_by_type(tp); PyErr_SetString(state->ProgrammingError, "Base Connection.__init__ not called."); return NULL; diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 4b1ca00dfa38a2..1d7c0b46a616d4 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -966,17 +966,16 @@ pysqlite_cursor_setoutputsize_impl(pysqlite_Cursor *self, PyObject *size, /*[clinic input] _sqlite3.Cursor.close as pysqlite_cursor_close - cls: defining_class - Closes the cursor. [clinic start generated code]*/ static PyObject * -pysqlite_cursor_close_impl(pysqlite_Cursor *self, PyTypeObject *cls) -/*[clinic end generated code: output=a08ab3d772f45438 input=28ba9b532ab46ba0]*/ +pysqlite_cursor_close_impl(pysqlite_Cursor *self) +/*[clinic end generated code: output=b6055e4ec6fe63b6 input=08b36552dbb9a986]*/ { if (!self->connection) { - pysqlite_state *state = pysqlite_get_state_by_cls(cls); + PyTypeObject *tp = Py_TYPE(self); + pysqlite_state *state = pysqlite_get_state_by_type(tp); PyErr_SetString(state->ProgrammingError, "Base Cursor.__init__ not called."); return NULL; diff --git a/Modules/_sqlite/module.h b/Modules/_sqlite/module.h index 9cba90e9353e8c..d5eb99a86efcd1 100644 --- a/Modules/_sqlite/module.h +++ b/Modules/_sqlite/module.h @@ -70,14 +70,6 @@ pysqlite_get_state(PyObject *module) return state; } -static inline pysqlite_state * -pysqlite_get_state_by_cls(PyTypeObject *cls) -{ - pysqlite_state *state = (pysqlite_state *)PyType_GetModuleState(cls); - assert(state != NULL); - return state; -} - struct PyModuleDef _sqlite3module; static inline pysqlite_state * pysqlite_get_state_by_type(PyTypeObject *tp) From 5da6ded766bb2fa3f3131ece03c7ff69e1a6052c Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 26 Oct 2021 18:53:01 +0200 Subject: [PATCH 4/4] Address review --- Modules/_sqlite/module.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/_sqlite/module.h b/Modules/_sqlite/module.h index d5eb99a86efcd1..1d319f1ed5541e 100644 --- a/Modules/_sqlite/module.h +++ b/Modules/_sqlite/module.h @@ -70,7 +70,7 @@ pysqlite_get_state(PyObject *module) return state; } -struct PyModuleDef _sqlite3module; +extern struct PyModuleDef _sqlite3module; static inline pysqlite_state * pysqlite_get_state_by_type(PyTypeObject *tp) {