Skip to content

Commit 10a5c80

Browse files
author
Erlend Egeberg Aasland
authored
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
1 parent 8ebd944 commit 10a5c80

File tree

12 files changed

+103
-70
lines changed

12 files changed

+103
-70
lines changed

Modules/_sqlite/clinic/connection.c.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -552,8 +552,8 @@ pysqlite_connection_backup(pysqlite_Connection *self, PyObject *const *args, Py_
552552
if (!args) {
553553
goto exit;
554554
}
555-
if (!PyObject_TypeCheck(args[0], pysqlite_ConnectionType)) {
556-
_PyArg_BadArgument("backup", "argument 'target'", (pysqlite_ConnectionType)->tp_name, args[0]);
555+
if (!PyObject_TypeCheck(args[0], clinic_state()->ConnectionType)) {
556+
_PyArg_BadArgument("backup", "argument 'target'", (clinic_state()->ConnectionType)->tp_name, args[0]);
557557
goto exit;
558558
}
559559
target = (pysqlite_Connection *)args[0];
@@ -710,4 +710,4 @@ pysqlite_connection_exit(pysqlite_Connection *self, PyObject *const *args, Py_ss
710710
#ifndef PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF
711711
#define PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF
712712
#endif /* !defined(PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF) */
713-
/*[clinic end generated code: output=c1bf09db3bcd0105 input=a9049054013a1b77]*/
713+
/*[clinic end generated code: output=1ee2f6173f4acec3 input=a9049054013a1b77]*/

Modules/_sqlite/clinic/cursor.c.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@ pysqlite_cursor_init(PyObject *self, PyObject *args, PyObject *kwargs)
1212
int return_value = -1;
1313
pysqlite_Connection *connection;
1414

15-
if (Py_IS_TYPE(self, pysqlite_CursorType) &&
15+
if (Py_IS_TYPE(self, clinic_state()->CursorType) &&
1616
!_PyArg_NoKeywords("Cursor", kwargs)) {
1717
goto exit;
1818
}
1919
if (!_PyArg_CheckPositional("Cursor", PyTuple_GET_SIZE(args), 1, 1)) {
2020
goto exit;
2121
}
22-
if (!PyObject_TypeCheck(PyTuple_GET_ITEM(args, 0), pysqlite_ConnectionType)) {
23-
_PyArg_BadArgument("Cursor", "argument 1", (pysqlite_ConnectionType)->tp_name, PyTuple_GET_ITEM(args, 0));
22+
if (!PyObject_TypeCheck(PyTuple_GET_ITEM(args, 0), clinic_state()->ConnectionType)) {
23+
_PyArg_BadArgument("Cursor", "argument 1", (clinic_state()->ConnectionType)->tp_name, PyTuple_GET_ITEM(args, 0));
2424
goto exit;
2525
}
2626
connection = (pysqlite_Connection *)PyTuple_GET_ITEM(args, 0);
@@ -259,4 +259,4 @@ pysqlite_cursor_close(pysqlite_Cursor *self, PyObject *Py_UNUSED(ignored))
259259
{
260260
return pysqlite_cursor_close_impl(self);
261261
}
262-
/*[clinic end generated code: output=6a2d4d49784aa686 input=a9049054013a1b77]*/
262+
/*[clinic end generated code: output=e3a502bb26aaefa5 input=a9049054013a1b77]*/

Modules/_sqlite/clinic/module.c.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ pysqlite_adapt(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
198198
{
199199
PyObject *return_value = NULL;
200200
PyObject *obj;
201-
PyObject *proto = (PyObject*)pysqlite_PrepareProtocolType;
201+
PyObject *proto = (PyObject *)clinic_state()->PrepareProtocolType;
202202
PyObject *alt = NULL;
203203

204204
if (!_PyArg_CheckPositional("adapt", nargs, 1, 3)) {
@@ -219,4 +219,4 @@ pysqlite_adapt(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
219219
exit:
220220
return return_value;
221221
}
222-
/*[clinic end generated code: output=d87990f941c209fa input=a9049054013a1b77]*/
222+
/*[clinic end generated code: output=e9c2442673289cab input=a9049054013a1b77]*/

Modules/_sqlite/clinic/row.c.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@ pysqlite_row_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1313
pysqlite_Cursor *cursor;
1414
PyObject *data;
1515

16-
if ((type == pysqlite_RowType) &&
16+
if ((type == clinic_state()->RowType) &&
1717
!_PyArg_NoKeywords("Row", kwargs)) {
1818
goto exit;
1919
}
2020
if (!_PyArg_CheckPositional("Row", PyTuple_GET_SIZE(args), 2, 2)) {
2121
goto exit;
2222
}
23-
if (!PyObject_TypeCheck(PyTuple_GET_ITEM(args, 0), pysqlite_CursorType)) {
24-
_PyArg_BadArgument("Row", "argument 1", (pysqlite_CursorType)->tp_name, PyTuple_GET_ITEM(args, 0));
23+
if (!PyObject_TypeCheck(PyTuple_GET_ITEM(args, 0), clinic_state()->CursorType)) {
24+
_PyArg_BadArgument("Row", "argument 1", (clinic_state()->CursorType)->tp_name, PyTuple_GET_ITEM(args, 0));
2525
goto exit;
2626
}
2727
cursor = (pysqlite_Cursor *)PyTuple_GET_ITEM(args, 0);
@@ -53,4 +53,4 @@ pysqlite_row_keys(pysqlite_Row *self, PyObject *Py_UNUSED(ignored))
5353
{
5454
return pysqlite_row_keys_impl(self);
5555
}
56-
/*[clinic end generated code: output=8d29220b9cde035d input=a9049054013a1b77]*/
56+
/*[clinic end generated code: output=0382771b4fc85f36 input=a9049054013a1b77]*/

Modules/_sqlite/connection.c

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,15 @@
3636
#define HAVE_TRACE_V2
3737
#endif
3838

39+
#define clinic_state() (pysqlite_get_state(NULL))
3940
#include "clinic/connection.c.h"
41+
#undef clinic_state
42+
4043
/*[clinic input]
4144
module _sqlite3
42-
class _sqlite3.Connection "pysqlite_Connection *" "pysqlite_ConnectionType"
45+
class _sqlite3.Connection "pysqlite_Connection *" "clinic_state()->ConnectionType"
4346
[clinic start generated code]*/
44-
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=aa796073bd8f69db]*/
47+
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=67369db2faf80891]*/
4548

4649
_Py_IDENTIFIER(cursor);
4750

@@ -339,14 +342,15 @@ pysqlite_connection_cursor_impl(pysqlite_Connection *self, PyObject *factory)
339342
return NULL;
340343
}
341344

345+
pysqlite_state *state = pysqlite_get_state(NULL);
342346
if (factory == NULL) {
343-
factory = (PyObject*)pysqlite_CursorType;
347+
factory = (PyObject *)state->CursorType;
344348
}
345349

346350
cursor = PyObject_CallOneArg(factory, (PyObject *)self);
347351
if (cursor == NULL)
348352
return NULL;
349-
if (!PyObject_TypeCheck(cursor, pysqlite_CursorType)) {
353+
if (!PyObject_TypeCheck(cursor, state->CursorType)) {
350354
PyErr_Format(PyExc_TypeError,
351355
"factory must return a cursor, not %.100s",
352356
Py_TYPE(cursor)->tp_name);
@@ -1592,7 +1596,7 @@ pysqlite_connection_iterdump_impl(pysqlite_Connection *self)
15921596
/*[clinic input]
15931597
_sqlite3.Connection.backup as pysqlite_connection_backup
15941598
1595-
target: object(type='pysqlite_Connection *', subclass_of='pysqlite_ConnectionType')
1599+
target: object(type='pysqlite_Connection *', subclass_of='clinic_state()->ConnectionType')
15961600
*
15971601
pages: int = -1
15981602
progress: object = None
@@ -1607,7 +1611,7 @@ pysqlite_connection_backup_impl(pysqlite_Connection *self,
16071611
pysqlite_Connection *target, int pages,
16081612
PyObject *progress, const char *name,
16091613
double sleep)
1610-
/*[clinic end generated code: output=306a3e6a38c36334 input=30ae45fc420bfd3b]*/
1614+
/*[clinic end generated code: output=306a3e6a38c36334 input=c759627ab1ad46ff]*/
16111615
{
16121616
int rc;
16131617
int sleep_ms = (int)(sleep * 1000.0);
@@ -1914,14 +1918,14 @@ static PyType_Spec connection_spec = {
19141918
.slots = connection_slots,
19151919
};
19161920

1917-
PyTypeObject *pysqlite_ConnectionType = NULL;
1918-
19191921
int
19201922
pysqlite_connection_setup_types(PyObject *module)
19211923
{
1922-
pysqlite_ConnectionType = (PyTypeObject *)PyType_FromModuleAndSpec(module, &connection_spec, NULL);
1923-
if (pysqlite_ConnectionType == NULL) {
1924+
PyObject *type = PyType_FromModuleAndSpec(module, &connection_spec, NULL);
1925+
if (type == NULL) {
19241926
return -1;
19251927
}
1928+
pysqlite_state *state = pysqlite_get_state(module);
1929+
state->ConnectionType = (PyTypeObject *)type;
19261930
return 0;
19271931
}

Modules/_sqlite/cursor.c

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,28 +24,31 @@
2424
#include "cursor.h"
2525
#include "module.h"
2626
#include "util.h"
27+
28+
#define clinic_state() (pysqlite_get_state(NULL))
2729
#include "clinic/cursor.c.h"
30+
#undef clinic_state
2831

2932
/*[clinic input]
3033
module _sqlite3
31-
class _sqlite3.Cursor "pysqlite_Cursor *" "pysqlite_CursorType"
34+
class _sqlite3.Cursor "pysqlite_Cursor *" "clinic_state()->CursorType"
3235
[clinic start generated code]*/
33-
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=b2072d8db95411d5]*/
36+
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3c5b8115c5cf30f1]*/
3437

3538
static const char errmsg_fetch_across_rollback[] = "Cursor needed to be reset because of commit/rollback and can no longer be fetched from.";
3639

3740
/*[clinic input]
3841
_sqlite3.Cursor.__init__ as pysqlite_cursor_init
3942
40-
connection: object(type='pysqlite_Connection *', subclass_of='pysqlite_ConnectionType')
43+
connection: object(type='pysqlite_Connection *', subclass_of='clinic_state()->ConnectionType')
4144
/
4245
4346
[clinic start generated code]*/
4447

4548
static int
4649
pysqlite_cursor_init_impl(pysqlite_Cursor *self,
4750
pysqlite_Connection *connection)
48-
/*[clinic end generated code: output=ac59dce49a809ca8 input=a8a4f75ac90999b2]*/
51+
/*[clinic end generated code: output=ac59dce49a809ca8 input=23d4265b534989fb]*/
4952
{
5053
Py_INCREF(connection);
5154
Py_XSETREF(self->connection, connection);
@@ -1079,14 +1082,14 @@ static PyType_Spec cursor_spec = {
10791082
.slots = cursor_slots,
10801083
};
10811084

1082-
PyTypeObject *pysqlite_CursorType = NULL;
1083-
10841085
int
10851086
pysqlite_cursor_setup_types(PyObject *module)
10861087
{
1087-
pysqlite_CursorType = (PyTypeObject *)PyType_FromModuleAndSpec(module, &cursor_spec, NULL);
1088-
if (pysqlite_CursorType == NULL) {
1088+
PyObject *type = PyType_FromModuleAndSpec(module, &cursor_spec, NULL);
1089+
if (type == NULL) {
10891090
return -1;
10901091
}
1092+
pysqlite_state *state = pysqlite_get_state(module);
1093+
state->CursorType = (PyTypeObject *)type;
10911094
return 0;
10921095
}

Modules/_sqlite/microprotocols.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ pysqlite_microprotocols_add(PyTypeObject *type, PyObject *proto, PyObject *cast)
5858
PyObject* key;
5959
int rc;
6060

61-
if (proto == NULL) proto = (PyObject*)pysqlite_PrepareProtocolType;
62-
61+
assert(type != NULL);
62+
assert(proto != NULL);
6363
key = Py_BuildValue("(OO)", (PyObject*)type, proto);
6464
if (!key) {
6565
return -1;
@@ -81,7 +81,7 @@ pysqlite_microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt)
8181
PyObject *adapter, *key, *adapted;
8282

8383
/* we don't check for exact type conformance as specified in PEP 246
84-
because the pysqlite_PrepareProtocolType type is abstract and there is no
84+
because the PrepareProtocolType type is abstract and there is no
8585
way to get a quotable object to be its instance */
8686

8787
/* look for an adapter in the registry */

Modules/_sqlite/module.c

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@
3232
#error "SQLite 3.7.15 or higher required"
3333
#endif
3434

35+
#define clinic_state() (pysqlite_get_state(NULL))
3536
#include "clinic/module.c.h"
37+
#undef clinic_state
38+
3639
/*[clinic input]
3740
module _sqlite3
3841
[clinic start generated code]*/
@@ -57,12 +60,6 @@ int pysqlite_BaseTypeAdapted = 0;
5760

5861
pysqlite_state pysqlite_global_state;
5962

60-
pysqlite_state *
61-
pysqlite_get_state(PyObject *Py_UNUSED(module))
62-
{
63-
return &pysqlite_global_state;
64-
}
65-
6663
static PyObject* module_connect(PyObject* self, PyObject* args, PyObject*
6764
kwargs)
6865
{
@@ -93,7 +90,8 @@ static PyObject* module_connect(PyObject* self, PyObject* args, PyObject*
9390
}
9491

9592
if (factory == NULL) {
96-
factory = (PyObject*)pysqlite_ConnectionType;
93+
pysqlite_state *state = pysqlite_get_state(self);
94+
factory = (PyObject *)state->ConnectionType;
9795
}
9896

9997
return PyObject_Call(factory, args, kwargs);
@@ -176,9 +174,12 @@ pysqlite_register_adapter_impl(PyObject *module, PyTypeObject *type,
176174
pysqlite_BaseTypeAdapted = 1;
177175
}
178176

179-
rc = pysqlite_microprotocols_add(type, (PyObject*)pysqlite_PrepareProtocolType, caster);
180-
if (rc == -1)
177+
pysqlite_state *state = pysqlite_get_state(NULL);
178+
PyObject *protocol = (PyObject *)state->PrepareProtocolType;
179+
rc = pysqlite_microprotocols_add(type, protocol, caster);
180+
if (rc == -1) {
181181
return NULL;
182+
}
182183

183184
Py_RETURN_NONE;
184185
}
@@ -240,7 +241,7 @@ pysqlite_enable_callback_trace_impl(PyObject *module, int enable)
240241
_sqlite3.adapt as pysqlite_adapt
241242
242243
obj: object
243-
proto: object(c_default='(PyObject*)pysqlite_PrepareProtocolType') = PrepareProtocolType
244+
proto: object(c_default='(PyObject *)clinic_state()->PrepareProtocolType') = PrepareProtocolType
244245
alt: object = NULL
245246
/
246247
@@ -250,7 +251,7 @@ Adapt given object to given protocol. Non-standard.
250251
static PyObject *
251252
pysqlite_adapt_impl(PyObject *module, PyObject *obj, PyObject *proto,
252253
PyObject *alt)
253-
/*[clinic end generated code: output=0c3927c5fcd23dd9 input=a58ab77fb5ae22dd]*/
254+
/*[clinic end generated code: output=0c3927c5fcd23dd9 input=c8995aeb25d0e542]*/
254255
{
255256
return pysqlite_microprotocols_adapt(obj, proto, alt);
256257
}
@@ -358,7 +359,7 @@ static struct PyModuleDef _sqlite3module = {
358359

359360
#define ADD_TYPE(module, type) \
360361
do { \
361-
if (PyModule_AddType(module, &type) < 0) { \
362+
if (PyModule_AddType(module, type) < 0) { \
362363
goto error; \
363364
} \
364365
} while (0)
@@ -392,6 +393,7 @@ PyMODINIT_FUNC PyInit__sqlite3(void)
392393
}
393394

394395
module = PyModule_Create(&_sqlite3module);
396+
pysqlite_state *state = pysqlite_get_state(module);
395397

396398
if (!module ||
397399
(pysqlite_row_setup_types(module) < 0) ||
@@ -403,10 +405,10 @@ PyMODINIT_FUNC PyInit__sqlite3(void)
403405
goto error;
404406
}
405407

406-
ADD_TYPE(module, *pysqlite_ConnectionType);
407-
ADD_TYPE(module, *pysqlite_CursorType);
408-
ADD_TYPE(module, *pysqlite_PrepareProtocolType);
409-
ADD_TYPE(module, *pysqlite_RowType);
408+
ADD_TYPE(module, state->ConnectionType);
409+
ADD_TYPE(module, state->CursorType);
410+
ADD_TYPE(module, state->PrepareProtocolType);
411+
ADD_TYPE(module, state->RowType);
410412

411413
/*** Create DB-API Exception hierarchy */
412414
ADD_EXCEPTION(module, "Error", pysqlite_Error, PyExc_Exception);

Modules/_sqlite/module.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,20 @@
3131

3232
typedef struct {
3333
PyObject *lru_cache;
34+
PyTypeObject *ConnectionType;
35+
PyTypeObject *CursorType;
36+
PyTypeObject *PrepareProtocolType;
37+
PyTypeObject *RowType;
38+
PyTypeObject *StatementType;
3439
} pysqlite_state;
3540

36-
extern pysqlite_state *pysqlite_get_state(PyObject *module);
41+
extern pysqlite_state pysqlite_global_state;
42+
43+
static inline pysqlite_state *
44+
pysqlite_get_state(PyObject *Py_UNUSED(module))
45+
{
46+
return &pysqlite_global_state;
47+
}
3748

3849
extern PyObject* pysqlite_Error;
3950
extern PyObject* pysqlite_Warning;

Modules/_sqlite/prepare_protocol.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,14 +60,14 @@ static PyType_Spec type_spec = {
6060
.slots = type_slots,
6161
};
6262

63-
PyTypeObject *pysqlite_PrepareProtocolType = NULL;
64-
6563
int
6664
pysqlite_prepare_protocol_setup_types(PyObject *module)
6765
{
68-
pysqlite_PrepareProtocolType = (PyTypeObject *)PyType_FromModuleAndSpec(module, &type_spec, NULL);
69-
if (pysqlite_PrepareProtocolType == NULL) {
66+
PyObject *type = PyType_FromModuleAndSpec(module, &type_spec, NULL);
67+
if (type == NULL) {
7068
return -1;
7169
}
70+
pysqlite_state *state = pysqlite_get_state(module);
71+
state->PrepareProtocolType = (PyTypeObject *)type;
7272
return 0;
7373
}

0 commit comments

Comments
 (0)