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

Modules/_sqlite/cache.c

Lines changed: 2 additions & 2 deletions
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;

Modules/_sqlite/connection.c

Lines changed: 1 addition & 1 deletion
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
}

Modules/_sqlite/cursor.c

Lines changed: 1 addition & 1 deletion
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
}

Modules/_sqlite/module.c

Lines changed: 3 additions & 3 deletions
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;

Modules/_sqlite/prepare_protocol.c

Lines changed: 1 addition & 1 deletion
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

Modules/_sqlite/row.c

Lines changed: 32 additions & 62 deletions
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
}

Modules/_sqlite/row.h

Lines changed: 2 additions & 2 deletions
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

Modules/_sqlite/statement.c

Lines changed: 27 additions & 44 deletions
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
}

Modules/_sqlite/statement.h

Lines changed: 2 additions & 2 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy