Skip to content

Commit a937ab4

Browse files
author
Erlend Egeberg Aasland
authored
bpo-41861: Convert _sqlite3 cache and node static types to heap types (GH-22417)
1 parent 00eb063 commit a937ab4

File tree

4 files changed

+48
-99
lines changed

4 files changed

+48
-99
lines changed

Modules/_sqlite/cache.c

+43-94
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ pysqlite_Node* pysqlite_new_node(PyObject* key, PyObject* data)
2929
{
3030
pysqlite_Node* node;
3131

32-
node = (pysqlite_Node*) (pysqlite_NodeType.tp_alloc(&pysqlite_NodeType, 0));
32+
node = (pysqlite_Node*) (pysqlite_NodeType->tp_alloc(pysqlite_NodeType, 0));
3333
if (!node) {
3434
return NULL;
3535
}
@@ -48,10 +48,13 @@ pysqlite_Node* pysqlite_new_node(PyObject* key, PyObject* data)
4848

4949
void pysqlite_node_dealloc(pysqlite_Node* self)
5050
{
51+
PyTypeObject *tp = Py_TYPE(self);
52+
5153
Py_DECREF(self->key);
5254
Py_DECREF(self->data);
5355

54-
Py_TYPE(self)->tp_free((PyObject*)self);
56+
tp->tp_free(self);
57+
Py_DECREF(tp);
5558
}
5659

5760
int pysqlite_cache_init(pysqlite_Cache* self, PyObject* args, PyObject* kwargs)
@@ -88,6 +91,7 @@ int pysqlite_cache_init(pysqlite_Cache* self, PyObject* args, PyObject* kwargs)
8891

8992
void pysqlite_cache_dealloc(pysqlite_Cache* self)
9093
{
94+
PyTypeObject *tp = Py_TYPE(self);
9195
pysqlite_Node* node;
9296
pysqlite_Node* delete_node;
9397

@@ -109,7 +113,8 @@ void pysqlite_cache_dealloc(pysqlite_Cache* self)
109113
}
110114
Py_DECREF(self->mapping);
111115

112-
Py_TYPE(self)->tp_free((PyObject*)self);
116+
tp->tp_free(self);
117+
Py_DECREF(tp);
113118
}
114119

115120
PyObject* pysqlite_cache_get(pysqlite_Cache* self, PyObject* key)
@@ -253,6 +258,20 @@ PyObject* pysqlite_cache_display(pysqlite_Cache* self, PyObject* args)
253258
Py_RETURN_NONE;
254259
}
255260

261+
static PyType_Slot pysqlite_NodeType_slots[] = {
262+
{Py_tp_dealloc, pysqlite_node_dealloc},
263+
{Py_tp_new, PyType_GenericNew},
264+
{0, NULL},
265+
};
266+
267+
static PyType_Spec pysqlite_NodeType_spec = {
268+
.name = MODULE_NAME ".Node",
269+
.basicsize = sizeof(pysqlite_Node),
270+
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE,
271+
.slots = pysqlite_NodeType_slots,
272+
};
273+
PyTypeObject *pysqlite_NodeType = NULL;
274+
256275
static PyMethodDef cache_methods[] = {
257276
{"get", (PyCFunction)pysqlite_cache_get, METH_O,
258277
PyDoc_STR("Gets an entry from the cache or calls the factory function to produce one.")},
@@ -261,102 +280,32 @@ static PyMethodDef cache_methods[] = {
261280
{NULL, NULL}
262281
};
263282

264-
PyTypeObject pysqlite_NodeType = {
265-
PyVarObject_HEAD_INIT(NULL, 0)
266-
MODULE_NAME "Node", /* tp_name */
267-
sizeof(pysqlite_Node), /* tp_basicsize */
268-
0, /* tp_itemsize */
269-
(destructor)pysqlite_node_dealloc, /* tp_dealloc */
270-
0, /* tp_vectorcall_offset */
271-
0, /* tp_getattr */
272-
0, /* tp_setattr */
273-
0, /* tp_as_async */
274-
0, /* tp_repr */
275-
0, /* tp_as_number */
276-
0, /* tp_as_sequence */
277-
0, /* tp_as_mapping */
278-
0, /* tp_hash */
279-
0, /* tp_call */
280-
0, /* tp_str */
281-
0, /* tp_getattro */
282-
0, /* tp_setattro */
283-
0, /* tp_as_buffer */
284-
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
285-
0, /* tp_doc */
286-
0, /* tp_traverse */
287-
0, /* tp_clear */
288-
0, /* tp_richcompare */
289-
0, /* tp_weaklistoffset */
290-
0, /* tp_iter */
291-
0, /* tp_iternext */
292-
0, /* tp_methods */
293-
0, /* tp_members */
294-
0, /* tp_getset */
295-
0, /* tp_base */
296-
0, /* tp_dict */
297-
0, /* tp_descr_get */
298-
0, /* tp_descr_set */
299-
0, /* tp_dictoffset */
300-
(initproc)0, /* tp_init */
301-
0, /* tp_alloc */
302-
0, /* tp_new */
303-
0 /* tp_free */
283+
static PyType_Slot pysqlite_CacheType_slots[] = {
284+
{Py_tp_dealloc, pysqlite_cache_dealloc},
285+
{Py_tp_methods, cache_methods},
286+
{Py_tp_new, PyType_GenericNew},
287+
{Py_tp_init, pysqlite_cache_init},
288+
{0, NULL},
304289
};
305290

306-
PyTypeObject pysqlite_CacheType = {
307-
PyVarObject_HEAD_INIT(NULL, 0)
308-
MODULE_NAME ".Cache", /* tp_name */
309-
sizeof(pysqlite_Cache), /* tp_basicsize */
310-
0, /* tp_itemsize */
311-
(destructor)pysqlite_cache_dealloc, /* tp_dealloc */
312-
0, /* tp_vectorcall_offset */
313-
0, /* tp_getattr */
314-
0, /* tp_setattr */
315-
0, /* tp_as_async */
316-
0, /* tp_repr */
317-
0, /* tp_as_number */
318-
0, /* tp_as_sequence */
319-
0, /* tp_as_mapping */
320-
0, /* tp_hash */
321-
0, /* tp_call */
322-
0, /* tp_str */
323-
0, /* tp_getattro */
324-
0, /* tp_setattro */
325-
0, /* tp_as_buffer */
326-
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
327-
0, /* tp_doc */
328-
0, /* tp_traverse */
329-
0, /* tp_clear */
330-
0, /* tp_richcompare */
331-
0, /* tp_weaklistoffset */
332-
0, /* tp_iter */
333-
0, /* tp_iternext */
334-
cache_methods, /* tp_methods */
335-
0, /* tp_members */
336-
0, /* tp_getset */
337-
0, /* tp_base */
338-
0, /* tp_dict */
339-
0, /* tp_descr_get */
340-
0, /* tp_descr_set */
341-
0, /* tp_dictoffset */
342-
(initproc)pysqlite_cache_init, /* tp_init */
343-
0, /* tp_alloc */
344-
0, /* tp_new */
345-
0 /* tp_free */
291+
static PyType_Spec pysqlite_CacheType_spec = {
292+
.name = MODULE_NAME ".Cache",
293+
.basicsize = sizeof(pysqlite_Cache),
294+
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE,
295+
.slots = pysqlite_CacheType_slots,
346296
};
297+
PyTypeObject *pysqlite_CacheType = NULL;
347298

348-
extern int pysqlite_cache_setup_types(void)
299+
extern int pysqlite_cache_setup_types(PyObject *mod)
349300
{
350-
int rc;
351-
352-
pysqlite_NodeType.tp_new = PyType_GenericNew;
353-
pysqlite_CacheType.tp_new = PyType_GenericNew;
354-
355-
rc = PyType_Ready(&pysqlite_NodeType);
356-
if (rc < 0) {
357-
return rc;
301+
pysqlite_NodeType = (PyTypeObject *)PyType_FromModuleAndSpec(mod, &pysqlite_NodeType_spec, NULL);
302+
if (pysqlite_NodeType == NULL) {
303+
return -1;
358304
}
359305

360-
rc = PyType_Ready(&pysqlite_CacheType);
361-
return rc;
306+
pysqlite_CacheType = (PyTypeObject *)PyType_FromModuleAndSpec(mod, &pysqlite_CacheType_spec, NULL);
307+
if (pysqlite_CacheType == NULL) {
308+
return -1;
309+
}
310+
return 0;
362311
}

Modules/_sqlite/cache.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ typedef struct
5959
int decref_factory;
6060
} pysqlite_Cache;
6161

62-
extern PyTypeObject pysqlite_NodeType;
63-
extern PyTypeObject pysqlite_CacheType;
62+
extern PyTypeObject *pysqlite_NodeType;
63+
extern PyTypeObject *pysqlite_CacheType;
6464

6565
int pysqlite_node_init(pysqlite_Node* self, PyObject* args, PyObject* kwargs);
6666
void pysqlite_node_dealloc(pysqlite_Node* self);
@@ -69,6 +69,6 @@ int pysqlite_cache_init(pysqlite_Cache* self, PyObject* args, PyObject* kwargs);
6969
void pysqlite_cache_dealloc(pysqlite_Cache* self);
7070
PyObject* pysqlite_cache_get(pysqlite_Cache* self, PyObject* args);
7171

72-
int pysqlite_cache_setup_types(void);
72+
int pysqlite_cache_setup_types(PyObject *module);
7373

7474
#endif

Modules/_sqlite/connection.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject
133133
}
134134
Py_DECREF(isolation_level);
135135

136-
self->statement_cache = (pysqlite_Cache*)PyObject_CallFunction((PyObject*)&pysqlite_CacheType, "Oi", self, cached_statements);
136+
self->statement_cache = (pysqlite_Cache*)PyObject_CallFunction((PyObject*)pysqlite_CacheType, "Oi", self, cached_statements);
137137
if (PyErr_Occurred()) {
138138
return -1;
139139
}

Modules/_sqlite/module.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ PyMODINIT_FUNC PyInit__sqlite3(void)
355355
(pysqlite_row_setup_types() < 0) ||
356356
(pysqlite_cursor_setup_types() < 0) ||
357357
(pysqlite_connection_setup_types() < 0) ||
358-
(pysqlite_cache_setup_types() < 0) ||
358+
(pysqlite_cache_setup_types(module) < 0) ||
359359
(pysqlite_statement_setup_types() < 0) ||
360360
(pysqlite_prepare_protocol_setup_types() < 0)
361361
) {

0 commit comments

Comments
 (0)