Skip to content

Commit 9031bd4

Browse files
author
Erlend Egeberg Aasland
authored
bpo-41861: Convert _sqlite3 RowType and StatementType to heap types (GH-22444)
1 parent fa7ce08 commit 9031bd4

File tree

9 files changed

+71
-118
lines changed

9 files changed

+71
-118
lines changed

Diff for: Modules/_sqlite/cache.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ static PyType_Slot pysqlite_NodeType_slots[] = {
267267
static PyType_Spec pysqlite_NodeType_spec = {
268268
.name = MODULE_NAME ".Node",
269269
.basicsize = sizeof(pysqlite_Node),
270-
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE,
270+
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
271271
.slots = pysqlite_NodeType_slots,
272272
};
273273
PyTypeObject *pysqlite_NodeType = NULL;
@@ -291,7 +291,7 @@ static PyType_Slot pysqlite_CacheType_slots[] = {
291291
static PyType_Spec pysqlite_CacheType_spec = {
292292
.name = MODULE_NAME ".Cache",
293293
.basicsize = sizeof(pysqlite_Cache),
294-
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE,
294+
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
295295
.slots = pysqlite_CacheType_slots,
296296
};
297297
PyTypeObject *pysqlite_CacheType = NULL;

Diff for: Modules/_sqlite/connection.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1234,7 +1234,7 @@ PyObject* pysqlite_connection_call(pysqlite_Connection* self, PyObject* args, Py
12341234

12351235
_pysqlite_drop_unused_statement_references(self);
12361236

1237-
statement = PyObject_New(pysqlite_Statement, &pysqlite_StatementType);
1237+
statement = PyObject_New(pysqlite_Statement, pysqlite_StatementType);
12381238
if (!statement) {
12391239
return NULL;
12401240
}

Diff for: Modules/_sqlite/cursor.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,7 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* args)
472472

473473
if (self->statement->in_use) {
474474
Py_SETREF(self->statement,
475-
PyObject_New(pysqlite_Statement, &pysqlite_StatementType));
475+
PyObject_New(pysqlite_Statement, pysqlite_StatementType));
476476
if (!self->statement) {
477477
goto error;
478478
}

Diff for: Modules/_sqlite/module.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -352,11 +352,11 @@ PyMODINIT_FUNC PyInit__sqlite3(void)
352352
module = PyModule_Create(&_sqlite3module);
353353

354354
if (!module ||
355-
(pysqlite_row_setup_types() < 0) ||
355+
(pysqlite_row_setup_types(module) < 0) ||
356356
(pysqlite_cursor_setup_types() < 0) ||
357357
(pysqlite_connection_setup_types() < 0) ||
358358
(pysqlite_cache_setup_types(module) < 0) ||
359-
(pysqlite_statement_setup_types() < 0) ||
359+
(pysqlite_statement_setup_types(module) < 0) ||
360360
(pysqlite_prepare_protocol_setup_types(module) < 0)
361361
) {
362362
Py_XDECREF(module);
@@ -366,7 +366,7 @@ PyMODINIT_FUNC PyInit__sqlite3(void)
366366
ADD_TYPE(module, pysqlite_ConnectionType);
367367
ADD_TYPE(module, pysqlite_CursorType);
368368
ADD_TYPE(module, *pysqlite_PrepareProtocolType);
369-
ADD_TYPE(module, pysqlite_RowType);
369+
ADD_TYPE(module, *pysqlite_RowType);
370370

371371
if (!(dict = PyModule_GetDict(module))) {
372372
goto error;

Diff for: Modules/_sqlite/prepare_protocol.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ static PyType_Slot type_slots[] = {
4646
static PyType_Spec type_spec = {
4747
.name = MODULE_NAME ".PrepareProtocol",
4848
.basicsize = sizeof(pysqlite_PrepareProtocol),
49-
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE,
49+
.flags = Py_TPFLAGS_DEFAULT,
5050
.slots = type_slots,
5151
};
5252

Diff for: Modules/_sqlite/row.c

+32-62
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,13 @@
2626

2727
void pysqlite_row_dealloc(pysqlite_Row* self)
2828
{
29+
PyTypeObject *tp = Py_TYPE(self);
30+
2931
Py_XDECREF(self->data);
3032
Py_XDECREF(self->description);
3133

32-
Py_TYPE(self)->tp_free((PyObject*)self);
34+
tp->tp_free(self);
35+
Py_DECREF(tp);
3336
}
3437

3538
static PyObject *
@@ -192,7 +195,7 @@ static PyObject* pysqlite_row_richcompare(pysqlite_Row *self, PyObject *_other,
192195
if (opid != Py_EQ && opid != Py_NE)
193196
Py_RETURN_NOTIMPLEMENTED;
194197

195-
if (PyObject_TypeCheck(_other, &pysqlite_RowType)) {
198+
if (PyObject_TypeCheck(_other, pysqlite_RowType)) {
196199
pysqlite_Row *other = (pysqlite_Row *)_other;
197200
int eq = PyObject_RichCompareBool(self->description, other->description, Py_EQ);
198201
if (eq < 0) {
@@ -206,73 +209,40 @@ static PyObject* pysqlite_row_richcompare(pysqlite_Row *self, PyObject *_other,
206209
Py_RETURN_NOTIMPLEMENTED;
207210
}
208211

209-
PyMappingMethods pysqlite_row_as_mapping = {
210-
/* mp_length */ (lenfunc)pysqlite_row_length,
211-
/* mp_subscript */ (binaryfunc)pysqlite_row_subscript,
212-
/* mp_ass_subscript */ (objobjargproc)0,
213-
};
214-
215-
static PySequenceMethods pysqlite_row_as_sequence = {
216-
/* sq_length */ (lenfunc)pysqlite_row_length,
217-
/* sq_concat */ 0,
218-
/* sq_repeat */ 0,
219-
/* sq_item */ (ssizeargfunc)pysqlite_row_item,
220-
};
221-
222-
223-
static PyMethodDef pysqlite_row_methods[] = {
212+
static PyMethodDef row_methods[] = {
224213
{"keys", (PyCFunction)pysqlite_row_keys, METH_NOARGS,
225214
PyDoc_STR("Returns the keys of the row.")},
226215
{NULL, NULL}
227216
};
228217

218+
static PyType_Slot row_slots[] = {
219+
{Py_tp_dealloc, pysqlite_row_dealloc},
220+
{Py_tp_hash, pysqlite_row_hash},
221+
{Py_tp_methods, row_methods},
222+
{Py_tp_richcompare, pysqlite_row_richcompare},
223+
{Py_tp_iter, pysqlite_iter},
224+
{Py_mp_length, pysqlite_row_length},
225+
{Py_mp_subscript, pysqlite_row_subscript},
226+
{Py_sq_length, pysqlite_row_length},
227+
{Py_sq_item, pysqlite_row_item},
228+
{Py_tp_new, pysqlite_row_new},
229+
{0, NULL},
230+
};
229231

230-
PyTypeObject pysqlite_RowType = {
231-
PyVarObject_HEAD_INIT(NULL, 0)
232-
MODULE_NAME ".Row", /* tp_name */
233-
sizeof(pysqlite_Row), /* tp_basicsize */
234-
0, /* tp_itemsize */
235-
(destructor)pysqlite_row_dealloc, /* tp_dealloc */
236-
0, /* tp_vectorcall_offset */
237-
0, /* tp_getattr */
238-
0, /* tp_setattr */
239-
0, /* tp_as_async */
240-
0, /* tp_repr */
241-
0, /* tp_as_number */
242-
0, /* tp_as_sequence */
243-
0, /* tp_as_mapping */
244-
(hashfunc)pysqlite_row_hash, /* tp_hash */
245-
0, /* tp_call */
246-
0, /* tp_str */
247-
0, /* tp_getattro */
248-
0, /* tp_setattro */
249-
0, /* tp_as_buffer */
250-
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
251-
0, /* tp_doc */
252-
(traverseproc)0, /* tp_traverse */
253-
0, /* tp_clear */
254-
(richcmpfunc)pysqlite_row_richcompare, /* tp_richcompare */
255-
0, /* tp_weaklistoffset */
256-
(getiterfunc)pysqlite_iter, /* tp_iter */
257-
0, /* tp_iternext */
258-
pysqlite_row_methods, /* tp_methods */
259-
0, /* tp_members */
260-
0, /* tp_getset */
261-
0, /* tp_base */
262-
0, /* tp_dict */
263-
0, /* tp_descr_get */
264-
0, /* tp_descr_set */
265-
0, /* tp_dictoffset */
266-
0, /* tp_init */
267-
0, /* tp_alloc */
268-
0, /* tp_new */
269-
0 /* tp_free */
232+
static PyType_Spec row_spec = {
233+
.name = MODULE_NAME ".Row",
234+
.basicsize = sizeof(pysqlite_Row),
235+
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
236+
.slots = row_slots,
270237
};
271238

272-
extern int pysqlite_row_setup_types(void)
239+
PyTypeObject *pysqlite_RowType = NULL;
240+
241+
extern int pysqlite_row_setup_types(PyObject *module)
273242
{
274-
pysqlite_RowType.tp_new = pysqlite_row_new;
275-
pysqlite_RowType.tp_as_mapping = &pysqlite_row_as_mapping;
276-
pysqlite_RowType.tp_as_sequence = &pysqlite_row_as_sequence;
277-
return PyType_Ready(&pysqlite_RowType);
243+
pysqlite_RowType = (PyTypeObject *)PyType_FromModuleAndSpec(module, &row_spec, NULL);
244+
if (pysqlite_RowType == NULL) {
245+
return -1;
246+
}
247+
return 0;
278248
}

Diff for: Modules/_sqlite/row.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ typedef struct _Row
3333
PyObject* description;
3434
} pysqlite_Row;
3535

36-
extern PyTypeObject pysqlite_RowType;
36+
extern PyTypeObject *pysqlite_RowType;
3737

38-
int pysqlite_row_setup_types(void);
38+
int pysqlite_row_setup_types(PyObject *module);
3939

4040
#endif

Diff for: Modules/_sqlite/statement.c

+27-44
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,8 @@ void pysqlite_statement_mark_dirty(pysqlite_Statement* self)
371371

372372
void pysqlite_statement_dealloc(pysqlite_Statement* self)
373373
{
374+
PyTypeObject *tp = Py_TYPE(self);
375+
374376
if (self->st) {
375377
Py_BEGIN_ALLOW_THREADS
376378
sqlite3_finalize(self->st);
@@ -385,7 +387,8 @@ void pysqlite_statement_dealloc(pysqlite_Statement* self)
385387
PyObject_ClearWeakRefs((PyObject*)self);
386388
}
387389

388-
Py_TYPE(self)->tp_free((PyObject*)self);
390+
tp->tp_free(self);
391+
Py_DECREF(tp);
389392
}
390393

391394
/*
@@ -458,50 +461,30 @@ static int pysqlite_check_remaining_sql(const char* tail)
458461
return 0;
459462
}
460463

461-
PyTypeObject pysqlite_StatementType = {
462-
PyVarObject_HEAD_INIT(NULL, 0)
463-
MODULE_NAME ".Statement", /* tp_name */
464-
sizeof(pysqlite_Statement), /* tp_basicsize */
465-
0, /* tp_itemsize */
466-
(destructor)pysqlite_statement_dealloc, /* tp_dealloc */
467-
0, /* tp_vectorcall_offset */
468-
0, /* tp_getattr */
469-
0, /* tp_setattr */
470-
0, /* tp_as_async */
471-
0, /* tp_repr */
472-
0, /* tp_as_number */
473-
0, /* tp_as_sequence */
474-
0, /* tp_as_mapping */
475-
0, /* tp_hash */
476-
0, /* tp_call */
477-
0, /* tp_str */
478-
0, /* tp_getattro */
479-
0, /* tp_setattro */
480-
0, /* tp_as_buffer */
481-
Py_TPFLAGS_DEFAULT, /* tp_flags */
482-
0, /* tp_doc */
483-
0, /* tp_traverse */
484-
0, /* tp_clear */
485-
0, /* tp_richcompare */
486-
offsetof(pysqlite_Statement, in_weakreflist), /* tp_weaklistoffset */
487-
0, /* tp_iter */
488-
0, /* tp_iternext */
489-
0, /* tp_methods */
490-
0, /* tp_members */
491-
0, /* tp_getset */
492-
0, /* tp_base */
493-
0, /* tp_dict */
494-
0, /* tp_descr_get */
495-
0, /* tp_descr_set */
496-
0, /* tp_dictoffset */
497-
(initproc)0, /* tp_init */
498-
0, /* tp_alloc */
499-
0, /* tp_new */
500-
0 /* tp_free */
464+
static PyMemberDef stmt_members[] = {
465+
{"__weaklistoffset__", T_PYSSIZET, offsetof(pysqlite_Statement, in_weakreflist), READONLY},
466+
{NULL},
467+
};
468+
static PyType_Slot stmt_slots[] = {
469+
{Py_tp_members, stmt_members},
470+
{Py_tp_dealloc, pysqlite_statement_dealloc},
471+
{Py_tp_new, PyType_GenericNew},
472+
{0, NULL},
473+
};
474+
475+
static PyType_Spec stmt_spec = {
476+
.name = MODULE_NAME ".Statement",
477+
.basicsize = sizeof(pysqlite_Statement),
478+
.flags = Py_TPFLAGS_DEFAULT,
479+
.slots = stmt_slots,
501480
};
481+
PyTypeObject *pysqlite_StatementType = NULL;
502482

503-
extern int pysqlite_statement_setup_types(void)
483+
extern int pysqlite_statement_setup_types(PyObject *module)
504484
{
505-
pysqlite_StatementType.tp_new = PyType_GenericNew;
506-
return PyType_Ready(&pysqlite_StatementType);
485+
pysqlite_StatementType = (PyTypeObject *)PyType_FromModuleAndSpec(module, &stmt_spec, NULL);
486+
if (pysqlite_StatementType == NULL) {
487+
return -1;
488+
}
489+
return 0;
507490
}

Diff for: Modules/_sqlite/statement.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ typedef struct
4343
PyObject* in_weakreflist; /* List of weak references */
4444
} pysqlite_Statement;
4545

46-
extern PyTypeObject pysqlite_StatementType;
46+
extern PyTypeObject *pysqlite_StatementType;
4747

4848
int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* connection, PyObject* sql);
4949
void pysqlite_statement_dealloc(pysqlite_Statement* self);
@@ -55,6 +55,6 @@ int pysqlite_statement_finalize(pysqlite_Statement* self);
5555
int pysqlite_statement_reset(pysqlite_Statement* self);
5656
void pysqlite_statement_mark_dirty(pysqlite_Statement* self);
5757

58-
int pysqlite_statement_setup_types(void);
58+
int pysqlite_statement_setup_types(PyObject *module);
5959

6060
#endif

0 commit comments

Comments
 (0)