Skip to content

Commit 6343dfb

Browse files
authored
Merge pull request #545 from python/main
bpo-42064: Finalise establishing sqlite3 global state (pythonGH-27155)
2 parents a90ff7b + 4c0deb2 commit 6343dfb

File tree

6 files changed

+69
-53
lines changed

6 files changed

+69
-53
lines changed

Modules/_sqlite/connection.c

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -637,9 +637,11 @@ _pysqlite_func_callback(sqlite3_context *context, int argc, sqlite3_value **argv
637637
Py_DECREF(py_retval);
638638
}
639639
if (!ok) {
640-
if (_pysqlite_enable_callback_tracebacks) {
640+
pysqlite_state *state = pysqlite_get_state(NULL);
641+
if (state->enable_callback_tracebacks) {
641642
PyErr_Print();
642-
} else {
643+
}
644+
else {
643645
PyErr_Clear();
644646
}
645647
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_
669671

670672
if (PyErr_Occurred()) {
671673
*aggregate_instance = 0;
672-
if (_pysqlite_enable_callback_tracebacks) {
674+
675+
pysqlite_state *state = pysqlite_get_state(NULL);
676+
if (state->enable_callback_tracebacks) {
673677
PyErr_Print();
674-
} else {
678+
}
679+
else {
675680
PyErr_Clear();
676681
}
677682
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_
693698
Py_DECREF(args);
694699

695700
if (!function_result) {
696-
if (_pysqlite_enable_callback_tracebacks) {
701+
pysqlite_state *state = pysqlite_get_state(NULL);
702+
if (state->enable_callback_tracebacks) {
697703
PyErr_Print();
698-
} else {
704+
}
705+
else {
699706
PyErr_Clear();
700707
}
701708
sqlite3_result_error(context, "user-defined aggregate's 'step' method raised error", -1);
@@ -746,9 +753,11 @@ _pysqlite_final_callback(sqlite3_context *context)
746753
Py_DECREF(function_result);
747754
}
748755
if (!ok) {
749-
if (_pysqlite_enable_callback_tracebacks) {
756+
pysqlite_state *state = pysqlite_get_state(NULL);
757+
if (state->enable_callback_tracebacks) {
750758
PyErr_Print();
751-
} else {
759+
}
760+
else {
752761
PyErr_Clear();
753762
}
754763
sqlite3_result_error(context, "user-defined aggregate's 'finalize' method raised error", -1);
@@ -941,21 +950,27 @@ static int _authorizer_callback(void* user_arg, int action, const char* arg1, co
941950
ret = PyObject_CallFunction((PyObject*)user_arg, "issss", action, arg1, arg2, dbname, access_attempt_source);
942951

943952
if (ret == NULL) {
944-
if (_pysqlite_enable_callback_tracebacks)
953+
pysqlite_state *state = pysqlite_get_state(NULL);
954+
if (state->enable_callback_tracebacks) {
945955
PyErr_Print();
946-
else
956+
}
957+
else {
947958
PyErr_Clear();
959+
}
948960

949961
rc = SQLITE_DENY;
950962
}
951963
else {
952964
if (PyLong_Check(ret)) {
953965
rc = _PyLong_AsInt(ret);
954966
if (rc == -1 && PyErr_Occurred()) {
955-
if (_pysqlite_enable_callback_tracebacks)
967+
pysqlite_state *state = pysqlite_get_state(NULL);
968+
if (state->enable_callback_tracebacks) {
956969
PyErr_Print();
957-
else
970+
}
971+
else {
958972
PyErr_Clear();
973+
}
959974
rc = SQLITE_DENY;
960975
}
961976
}
@@ -979,9 +994,11 @@ static int _progress_handler(void* user_arg)
979994
ret = _PyObject_CallNoArg((PyObject*)user_arg);
980995

981996
if (!ret) {
982-
if (_pysqlite_enable_callback_tracebacks) {
997+
pysqlite_state *state = pysqlite_get_state(NULL);
998+
if (state->enable_callback_tracebacks) {
983999
PyErr_Print();
984-
} else {
1000+
}
1001+
else {
9851002
PyErr_Clear();
9861003
}
9871004

@@ -1030,9 +1047,11 @@ static void _trace_callback(void* user_arg, const char* statement_string)
10301047
if (ret) {
10311048
Py_DECREF(ret);
10321049
} else {
1033-
if (_pysqlite_enable_callback_tracebacks) {
1050+
pysqlite_state *state = pysqlite_get_state(NULL);
1051+
if (state->enable_callback_tracebacks) {
10341052
PyErr_Print();
1035-
} else {
1053+
}
1054+
else {
10361055
PyErr_Clear();
10371056
}
10381057
}

Modules/_sqlite/cursor.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,8 @@ _pysqlite_get_converter(const char *keystr, Py_ssize_t keylen)
147147
return NULL;
148148
}
149149

150-
retval = PyDict_GetItemWithError(_pysqlite_converters, upcase_key);
150+
pysqlite_state *state = pysqlite_get_state(NULL);
151+
retval = PyDict_GetItemWithError(state->converters, upcase_key);
151152
Py_DECREF(upcase_key);
152153

153154
return retval;
@@ -469,6 +470,7 @@ get_statement_from_cache(pysqlite_Cursor *self, PyObject *operation)
469470
static PyObject *
470471
_pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation, PyObject* second_argument)
471472
{
473+
pysqlite_state *state = pysqlite_get_state(NULL);
472474
PyObject* parameters_list = NULL;
473475
PyObject* parameters_iter = NULL;
474476
PyObject* parameters = NULL;
@@ -583,7 +585,7 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation
583585
if (rc != SQLITE_DONE && rc != SQLITE_ROW) {
584586
if (PyErr_Occurred()) {
585587
/* there was an error that occurred in a user-defined callback */
586-
if (_pysqlite_enable_callback_tracebacks) {
588+
if (state->enable_callback_tracebacks) {
587589
PyErr_Print();
588590
} else {
589591
PyErr_Clear();

Modules/_sqlite/microprotocols.c

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,24 +29,20 @@
2929
#include "microprotocols.h"
3030
#include "prepare_protocol.h"
3131

32-
/** the adapters registry **/
33-
34-
static PyObject *psyco_adapters = NULL;
3532

3633
/* pysqlite_microprotocols_init - initialize the adapters dictionary */
3734

3835
int
3936
pysqlite_microprotocols_init(PyObject *module)
4037
{
4138
/* create adapters dictionary and put it in module namespace */
42-
if ((psyco_adapters = PyDict_New()) == NULL) {
39+
pysqlite_state *state = pysqlite_get_state(module);
40+
state->psyco_adapters = PyDict_New();
41+
if (state->psyco_adapters == NULL) {
4342
return -1;
4443
}
4544

46-
int res = PyModule_AddObjectRef(module, "adapters", psyco_adapters);
47-
Py_DECREF(psyco_adapters);
48-
49-
return res;
45+
return PyModule_AddObjectRef(module, "adapters", state->psyco_adapters);
5046
}
5147

5248

@@ -65,7 +61,8 @@ pysqlite_microprotocols_add(PyTypeObject *type, PyObject *proto, PyObject *cast)
6561
return -1;
6662
}
6763

68-
rc = PyDict_SetItem(psyco_adapters, key, cast);
64+
pysqlite_state *state = pysqlite_get_state(NULL);
65+
rc = PyDict_SetItem(state->psyco_adapters, key, cast);
6966
Py_DECREF(key);
7067

7168
return rc;
@@ -89,7 +86,8 @@ pysqlite_microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt)
8986
if (!key) {
9087
return NULL;
9188
}
92-
adapter = PyDict_GetItemWithError(psyco_adapters, key);
89+
pysqlite_state *state = pysqlite_get_state(NULL);
90+
adapter = PyDict_GetItemWithError(state->psyco_adapters, key);
9391
Py_DECREF(key);
9492
if (adapter) {
9593
Py_INCREF(adapter);
@@ -143,7 +141,6 @@ pysqlite_microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt)
143141
return Py_NewRef(alt);
144142
}
145143
/* else set the right exception and return NULL */
146-
pysqlite_state *state = pysqlite_get_state(NULL);
147144
PyErr_SetString(state->ProgrammingError, "can't adapt");
148145
return NULL;
149146
}

Modules/_sqlite/module.c

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,6 @@ module _sqlite3
4141
[clinic start generated code]*/
4242
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=81e330492d57488e]*/
4343

44-
/* static objects at module-level */
45-
PyObject* _pysqlite_converters = NULL;
46-
int _pysqlite_enable_callback_tracebacks = 0;
47-
int pysqlite_BaseTypeAdapted = 0;
48-
4944
pysqlite_state pysqlite_global_state;
5045

5146
// NOTE: This must equal sqlite3.Connection.__init__ argument spec!
@@ -159,7 +154,8 @@ pysqlite_register_adapter_impl(PyObject *module, PyTypeObject *type,
159154
* (99 % of all usages) */
160155
if (type == &PyLong_Type || type == &PyFloat_Type
161156
|| type == &PyUnicode_Type || type == &PyByteArray_Type) {
162-
pysqlite_BaseTypeAdapted = 1;
157+
pysqlite_state *state = pysqlite_get_state(module);
158+
state->BaseTypeAdapted = 1;
163159
}
164160

165161
pysqlite_state *state = pysqlite_get_state(NULL);
@@ -197,7 +193,8 @@ pysqlite_register_converter_impl(PyObject *module, PyObject *orig_name,
197193
goto error;
198194
}
199195

200-
if (PyDict_SetItem(_pysqlite_converters, name, callable) != 0) {
196+
pysqlite_state *state = pysqlite_get_state(module);
197+
if (PyDict_SetItem(state->converters, name, callable) != 0) {
201198
goto error;
202199
}
203200

@@ -220,7 +217,8 @@ static PyObject *
220217
pysqlite_enable_callback_trace_impl(PyObject *module, int enable)
221218
/*[clinic end generated code: output=4ff1d051c698f194 input=cb79d3581eb77c40]*/
222219
{
223-
_pysqlite_enable_callback_tracebacks = enable;
220+
pysqlite_state *state = pysqlite_get_state(module);
221+
state->enable_callback_tracebacks = enable;
224222

225223
Py_RETURN_NONE;
226224
}
@@ -246,15 +244,13 @@ pysqlite_adapt_impl(PyObject *module, PyObject *obj, PyObject *proto,
246244

247245
static int converters_init(PyObject* module)
248246
{
249-
_pysqlite_converters = PyDict_New();
250-
if (!_pysqlite_converters) {
247+
pysqlite_state *state = pysqlite_get_state(module);
248+
state->converters = PyDict_New();
249+
if (state->converters == NULL) {
251250
return -1;
252251
}
253252

254-
int res = PyModule_AddObjectRef(module, "converters", _pysqlite_converters);
255-
Py_DECREF(_pysqlite_converters);
256-
257-
return res;
253+
return PyModule_AddObjectRef(module, "converters", state->converters);
258254
}
259255

260256
static int

Modules/_sqlite/module.h

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,17 @@ typedef struct {
4141
PyObject *ProgrammingError;
4242
PyObject *Warning;
4343

44+
45+
/* A dictionary, mapping column types (INTEGER, VARCHAR, etc.) to converter
46+
* functions, that convert the SQL value to the appropriate Python value.
47+
* The key is uppercase.
48+
*/
49+
PyObject *converters;
50+
4451
PyObject *lru_cache;
52+
PyObject *psyco_adapters; // The adapters registry
53+
int BaseTypeAdapted;
54+
int enable_callback_tracebacks;
4555

4656
PyTypeObject *ConnectionType;
4757
PyTypeObject *CursorType;
@@ -58,15 +68,6 @@ pysqlite_get_state(PyObject *Py_UNUSED(module))
5868
return &pysqlite_global_state;
5969
}
6070

61-
/* A dictionary, mapping column types (INTEGER, VARCHAR, etc.) to converter
62-
* functions, that convert the SQL value to the appropriate Python value.
63-
* The key is uppercase.
64-
*/
65-
extern PyObject* _pysqlite_converters;
66-
67-
extern int _pysqlite_enable_callback_tracebacks;
68-
extern int pysqlite_BaseTypeAdapted;
69-
7071
#define PARSE_DECLTYPES 1
7172
#define PARSE_COLNAMES 2
7273
#endif

Modules/_sqlite/statement.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,8 @@ int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObjec
211211
/* returns 0 if the object is one of Python's internal ones that don't need to be adapted */
212212
static int _need_adapt(PyObject* obj)
213213
{
214-
if (pysqlite_BaseTypeAdapted) {
214+
pysqlite_state *state = pysqlite_get_state(NULL);
215+
if (state->BaseTypeAdapted) {
215216
return 1;
216217
}
217218

0 commit comments

Comments
 (0)