From 33d9dc06fe6c86940bb4ffafdd4ad43bc81e3bb1 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Thu, 15 Jul 2021 00:29:14 +0200 Subject: [PATCH 1/4] Move _pysqlite_converters to global state --- Modules/_sqlite/cursor.c | 3 ++- Modules/_sqlite/module.c | 14 ++++++-------- Modules/_sqlite/module.h | 12 ++++++------ 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 07202dfbf57e17..d087dc4a820406 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -147,7 +147,8 @@ _pysqlite_get_converter(const char *keystr, Py_ssize_t keylen) return NULL; } - retval = PyDict_GetItemWithError(_pysqlite_converters, upcase_key); + pysqlite_state *state = pysqlite_get_state(NULL); + retval = PyDict_GetItemWithError(state->converters, upcase_key); Py_DECREF(upcase_key); return retval; diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c index 3d81ad8f140cae..b07c5c583c80cd 100644 --- a/Modules/_sqlite/module.c +++ b/Modules/_sqlite/module.c @@ -42,7 +42,6 @@ module _sqlite3 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=81e330492d57488e]*/ /* static objects at module-level */ -PyObject* _pysqlite_converters = NULL; int _pysqlite_enable_callback_tracebacks = 0; int pysqlite_BaseTypeAdapted = 0; @@ -197,7 +196,8 @@ pysqlite_register_converter_impl(PyObject *module, PyObject *orig_name, goto error; } - if (PyDict_SetItem(_pysqlite_converters, name, callable) != 0) { + pysqlite_state *state = pysqlite_get_state(module); + if (PyDict_SetItem(state->converters, name, callable) != 0) { goto error; } @@ -246,15 +246,13 @@ pysqlite_adapt_impl(PyObject *module, PyObject *obj, PyObject *proto, static int converters_init(PyObject* module) { - _pysqlite_converters = PyDict_New(); - if (!_pysqlite_converters) { + pysqlite_state *state = pysqlite_get_state(module); + state->converters = PyDict_New(); + if (state->converters == NULL) { return -1; } - int res = PyModule_AddObjectRef(module, "converters", _pysqlite_converters); - Py_DECREF(_pysqlite_converters); - - return res; + return PyModule_AddObjectRef(module, "converters", state->converters); } static int diff --git a/Modules/_sqlite/module.h b/Modules/_sqlite/module.h index 7ce8381df0c31e..a23f40ce894431 100644 --- a/Modules/_sqlite/module.h +++ b/Modules/_sqlite/module.h @@ -41,6 +41,12 @@ typedef struct { PyObject *ProgrammingError; PyObject *Warning; + /* A dictionary, mapping column types (INTEGER, VARCHAR, etc.) to converter + * functions, that convert the SQL value to the appropriate Python value. + * The key is uppercase. + */ + PyObject *converters; + PyObject *lru_cache; PyTypeObject *ConnectionType; @@ -58,12 +64,6 @@ pysqlite_get_state(PyObject *Py_UNUSED(module)) return &pysqlite_global_state; } -/* A dictionary, mapping column types (INTEGER, VARCHAR, etc.) to converter - * functions, that convert the SQL value to the appropriate Python value. - * The key is uppercase. - */ -extern PyObject* _pysqlite_converters; - extern int _pysqlite_enable_callback_tracebacks; extern int pysqlite_BaseTypeAdapted; From 8a3a681ca9f680fe01bd629fd0ffb2bd6c9ff21f Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Thu, 15 Jul 2021 00:36:21 +0200 Subject: [PATCH 2/4] Move _pysqlite_enable_callback_tracebacks to global state --- Modules/_sqlite/connection.c | 51 +++++++++++++++++++++++++----------- Modules/_sqlite/cursor.c | 3 ++- Modules/_sqlite/module.c | 4 +-- Modules/_sqlite/module.h | 2 +- 4 files changed, 40 insertions(+), 20 deletions(-) diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 64bd53aea7ea6a..4a6abb4636ecdb 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -637,9 +637,11 @@ _pysqlite_func_callback(sqlite3_context *context, int argc, sqlite3_value **argv Py_DECREF(py_retval); } if (!ok) { - if (_pysqlite_enable_callback_tracebacks) { + pysqlite_state *state = pysqlite_get_state(NULL); + if (state->enable_callback_tracebacks) { PyErr_Print(); - } else { + } + else { PyErr_Clear(); } sqlite3_result_error(context, "user-defined function raised exception", -1); @@ -669,9 +671,12 @@ static void _pysqlite_step_callback(sqlite3_context *context, int argc, sqlite3_ if (PyErr_Occurred()) { *aggregate_instance = 0; - if (_pysqlite_enable_callback_tracebacks) { + + pysqlite_state *state = pysqlite_get_state(NULL); + if (state->enable_callback_tracebacks) { PyErr_Print(); - } else { + } + else { PyErr_Clear(); } sqlite3_result_error(context, "user-defined aggregate's '__init__' method raised error", -1); @@ -693,9 +698,11 @@ static void _pysqlite_step_callback(sqlite3_context *context, int argc, sqlite3_ Py_DECREF(args); if (!function_result) { - if (_pysqlite_enable_callback_tracebacks) { + pysqlite_state *state = pysqlite_get_state(NULL); + if (state->enable_callback_tracebacks) { PyErr_Print(); - } else { + } + else { PyErr_Clear(); } sqlite3_result_error(context, "user-defined aggregate's 'step' method raised error", -1); @@ -746,9 +753,11 @@ _pysqlite_final_callback(sqlite3_context *context) Py_DECREF(function_result); } if (!ok) { - if (_pysqlite_enable_callback_tracebacks) { + pysqlite_state *state = pysqlite_get_state(NULL); + if (state->enable_callback_tracebacks) { PyErr_Print(); - } else { + } + else { PyErr_Clear(); } sqlite3_result_error(context, "user-defined aggregate's 'finalize' method raised error", -1); @@ -941,10 +950,13 @@ static int _authorizer_callback(void* user_arg, int action, const char* arg1, co ret = PyObject_CallFunction((PyObject*)user_arg, "issss", action, arg1, arg2, dbname, access_attempt_source); if (ret == NULL) { - if (_pysqlite_enable_callback_tracebacks) + pysqlite_state *state = pysqlite_get_state(NULL); + if (state->enable_callback_tracebacks) { PyErr_Print(); - else + } + else { PyErr_Clear(); + } rc = SQLITE_DENY; } @@ -952,10 +964,13 @@ static int _authorizer_callback(void* user_arg, int action, const char* arg1, co if (PyLong_Check(ret)) { rc = _PyLong_AsInt(ret); if (rc == -1 && PyErr_Occurred()) { - if (_pysqlite_enable_callback_tracebacks) + pysqlite_state *state = pysqlite_get_state(NULL); + if (state->enable_callback_tracebacks) { PyErr_Print(); - else + } + else { PyErr_Clear(); + } rc = SQLITE_DENY; } } @@ -979,9 +994,11 @@ static int _progress_handler(void* user_arg) ret = _PyObject_CallNoArg((PyObject*)user_arg); if (!ret) { - if (_pysqlite_enable_callback_tracebacks) { + pysqlite_state *state = pysqlite_get_state(NULL); + if (state->enable_callback_tracebacks) { PyErr_Print(); - } else { + } + else { PyErr_Clear(); } @@ -1030,9 +1047,11 @@ static void _trace_callback(void* user_arg, const char* statement_string) if (ret) { Py_DECREF(ret); } else { - if (_pysqlite_enable_callback_tracebacks) { + pysqlite_state *state = pysqlite_get_state(NULL); + if (state->enable_callback_tracebacks) { PyErr_Print(); - } else { + } + else { PyErr_Clear(); } } diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index d087dc4a820406..24b4a37521d836 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -470,6 +470,7 @@ get_statement_from_cache(pysqlite_Cursor *self, PyObject *operation) static PyObject * _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation, PyObject* second_argument) { + pysqlite_state *state = pysqlite_get_state(NULL); PyObject* parameters_list = NULL; PyObject* parameters_iter = NULL; PyObject* parameters = NULL; @@ -584,7 +585,7 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation if (rc != SQLITE_DONE && rc != SQLITE_ROW) { if (PyErr_Occurred()) { /* there was an error that occurred in a user-defined callback */ - if (_pysqlite_enable_callback_tracebacks) { + if (state->enable_callback_tracebacks) { PyErr_Print(); } else { PyErr_Clear(); diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c index b07c5c583c80cd..fa07e95d3983b3 100644 --- a/Modules/_sqlite/module.c +++ b/Modules/_sqlite/module.c @@ -42,7 +42,6 @@ module _sqlite3 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=81e330492d57488e]*/ /* static objects at module-level */ -int _pysqlite_enable_callback_tracebacks = 0; int pysqlite_BaseTypeAdapted = 0; pysqlite_state pysqlite_global_state; @@ -220,7 +219,8 @@ static PyObject * pysqlite_enable_callback_trace_impl(PyObject *module, int enable) /*[clinic end generated code: output=4ff1d051c698f194 input=cb79d3581eb77c40]*/ { - _pysqlite_enable_callback_tracebacks = enable; + pysqlite_state *state = pysqlite_get_state(module); + state->enable_callback_tracebacks = enable; Py_RETURN_NONE; } diff --git a/Modules/_sqlite/module.h b/Modules/_sqlite/module.h index a23f40ce894431..40c191dd04a678 100644 --- a/Modules/_sqlite/module.h +++ b/Modules/_sqlite/module.h @@ -47,6 +47,7 @@ typedef struct { */ PyObject *converters; + int enable_callback_tracebacks; PyObject *lru_cache; PyTypeObject *ConnectionType; @@ -64,7 +65,6 @@ pysqlite_get_state(PyObject *Py_UNUSED(module)) return &pysqlite_global_state; } -extern int _pysqlite_enable_callback_tracebacks; extern int pysqlite_BaseTypeAdapted; #define PARSE_DECLTYPES 1 From 650160dbc58340426b231998d5944a9b2667c966 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Thu, 15 Jul 2021 00:41:00 +0200 Subject: [PATCH 3/4] Move pysqlite_BaseTypeAdapted to global state --- Modules/_sqlite/module.c | 6 ++---- Modules/_sqlite/module.h | 6 +++--- Modules/_sqlite/statement.c | 3 ++- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c index fa07e95d3983b3..98b2c90108f07b 100644 --- a/Modules/_sqlite/module.c +++ b/Modules/_sqlite/module.c @@ -41,9 +41,6 @@ module _sqlite3 [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=81e330492d57488e]*/ -/* static objects at module-level */ -int pysqlite_BaseTypeAdapted = 0; - pysqlite_state pysqlite_global_state; // NOTE: This must equal sqlite3.Connection.__init__ argument spec! @@ -157,7 +154,8 @@ pysqlite_register_adapter_impl(PyObject *module, PyTypeObject *type, * (99 % of all usages) */ if (type == &PyLong_Type || type == &PyFloat_Type || type == &PyUnicode_Type || type == &PyByteArray_Type) { - pysqlite_BaseTypeAdapted = 1; + pysqlite_state *state = pysqlite_get_state(module); + state->BaseTypeAdapted = 1; } pysqlite_state *state = pysqlite_get_state(NULL); diff --git a/Modules/_sqlite/module.h b/Modules/_sqlite/module.h index 40c191dd04a678..f21e2b94ed3363 100644 --- a/Modules/_sqlite/module.h +++ b/Modules/_sqlite/module.h @@ -41,14 +41,16 @@ typedef struct { PyObject *ProgrammingError; PyObject *Warning; + /* A dictionary, mapping column types (INTEGER, VARCHAR, etc.) to converter * functions, that convert the SQL value to the appropriate Python value. * The key is uppercase. */ PyObject *converters; - int enable_callback_tracebacks; PyObject *lru_cache; + int BaseTypeAdapted; + int enable_callback_tracebacks; PyTypeObject *ConnectionType; PyTypeObject *CursorType; @@ -65,8 +67,6 @@ pysqlite_get_state(PyObject *Py_UNUSED(module)) return &pysqlite_global_state; } -extern int pysqlite_BaseTypeAdapted; - #define PARSE_DECLTYPES 1 #define PARSE_COLNAMES 2 #endif diff --git a/Modules/_sqlite/statement.c b/Modules/_sqlite/statement.c index cca8616fe2e796..8add50960f86a3 100644 --- a/Modules/_sqlite/statement.c +++ b/Modules/_sqlite/statement.c @@ -211,7 +211,8 @@ int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObjec /* returns 0 if the object is one of Python's internal ones that don't need to be adapted */ static int _need_adapt(PyObject* obj) { - if (pysqlite_BaseTypeAdapted) { + pysqlite_state *state = pysqlite_get_state(NULL); + if (state->BaseTypeAdapted) { return 1; } From 300ba6c142f41ccece916ec27d85cd419e25ed53 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Thu, 15 Jul 2021 00:48:52 +0200 Subject: [PATCH 4/4] Move psyco_adapters to global state --- Modules/_sqlite/microprotocols.c | 19 ++++++++----------- Modules/_sqlite/module.h | 1 + 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/Modules/_sqlite/microprotocols.c b/Modules/_sqlite/microprotocols.c index e72fc929a01017..160d7b923d7a1f 100644 --- a/Modules/_sqlite/microprotocols.c +++ b/Modules/_sqlite/microprotocols.c @@ -29,9 +29,6 @@ #include "microprotocols.h" #include "prepare_protocol.h" -/** the adapters registry **/ - -static PyObject *psyco_adapters = NULL; /* pysqlite_microprotocols_init - initialize the adapters dictionary */ @@ -39,14 +36,13 @@ int pysqlite_microprotocols_init(PyObject *module) { /* create adapters dictionary and put it in module namespace */ - if ((psyco_adapters = PyDict_New()) == NULL) { + pysqlite_state *state = pysqlite_get_state(module); + state->psyco_adapters = PyDict_New(); + if (state->psyco_adapters == NULL) { return -1; } - int res = PyModule_AddObjectRef(module, "adapters", psyco_adapters); - Py_DECREF(psyco_adapters); - - return res; + return PyModule_AddObjectRef(module, "adapters", state->psyco_adapters); } @@ -65,7 +61,8 @@ pysqlite_microprotocols_add(PyTypeObject *type, PyObject *proto, PyObject *cast) return -1; } - rc = PyDict_SetItem(psyco_adapters, key, cast); + pysqlite_state *state = pysqlite_get_state(NULL); + rc = PyDict_SetItem(state->psyco_adapters, key, cast); Py_DECREF(key); return rc; @@ -89,7 +86,8 @@ pysqlite_microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt) if (!key) { return NULL; } - adapter = PyDict_GetItemWithError(psyco_adapters, key); + pysqlite_state *state = pysqlite_get_state(NULL); + adapter = PyDict_GetItemWithError(state->psyco_adapters, key); Py_DECREF(key); if (adapter) { Py_INCREF(adapter); @@ -143,7 +141,6 @@ pysqlite_microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt) return Py_NewRef(alt); } /* else set the right exception and return NULL */ - pysqlite_state *state = pysqlite_get_state(NULL); PyErr_SetString(state->ProgrammingError, "can't adapt"); return NULL; } diff --git a/Modules/_sqlite/module.h b/Modules/_sqlite/module.h index f21e2b94ed3363..1344490700851f 100644 --- a/Modules/_sqlite/module.h +++ b/Modules/_sqlite/module.h @@ -49,6 +49,7 @@ typedef struct { PyObject *converters; PyObject *lru_cache; + PyObject *psyco_adapters; // The adapters registry int BaseTypeAdapted; int enable_callback_tracebacks;