From 9fc9c5e5124aa8321bfd8a868c94cf458820d743 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 8 Sep 2020 23:04:43 +0200 Subject: [PATCH 1/8] Convert CacheType to heap type --- Modules/_sqlite/cache.c | 79 +++++++++++++----------------------- Modules/_sqlite/cache.h | 2 +- Modules/_sqlite/connection.c | 2 +- 3 files changed, 30 insertions(+), 53 deletions(-) diff --git a/Modules/_sqlite/cache.c b/Modules/_sqlite/cache.c index 758fc022f78108..229b34a4e25004 100644 --- a/Modules/_sqlite/cache.c +++ b/Modules/_sqlite/cache.c @@ -110,6 +110,7 @@ void pysqlite_cache_dealloc(pysqlite_Cache* self) Py_DECREF(self->mapping); Py_TYPE(self)->tp_free((PyObject*)self); + Py_DECREF(pysqlite_CacheType); } PyObject* pysqlite_cache_get(pysqlite_Cache* self, PyObject* key) @@ -253,14 +254,6 @@ PyObject* pysqlite_cache_display(pysqlite_Cache* self, PyObject* args) Py_RETURN_NONE; } -static PyMethodDef cache_methods[] = { - {"get", (PyCFunction)pysqlite_cache_get, METH_O, - PyDoc_STR("Gets an entry from the cache or calls the factory function to produce one.")}, - {"display", (PyCFunction)pysqlite_cache_display, METH_NOARGS, - PyDoc_STR("For debugging only.")}, - {NULL, NULL} -}; - PyTypeObject pysqlite_NodeType = { PyVarObject_HEAD_INIT(NULL, 0) MODULE_NAME "Node", /* tp_name */ @@ -303,60 +296,44 @@ PyTypeObject pysqlite_NodeType = { 0 /* tp_free */ }; -PyTypeObject pysqlite_CacheType = { - PyVarObject_HEAD_INIT(NULL, 0) - MODULE_NAME ".Cache", /* tp_name */ - sizeof(pysqlite_Cache), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pysqlite_cache_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - cache_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)pysqlite_cache_init, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0 /* tp_free */ +static PyMethodDef cache_methods[] = { + {"get", (PyCFunction)pysqlite_cache_get, METH_O, + PyDoc_STR("Gets an entry from the cache or calls the factory function to produce one.")}, + {"display", (PyCFunction)pysqlite_cache_display, METH_NOARGS, + PyDoc_STR("For debugging only.")}, + {NULL, NULL} }; +static PyType_Slot pysqlite_CacheType_slots[] = { + {Py_tp_dealloc, pysqlite_cache_dealloc}, + {Py_tp_methods, cache_methods}, + {Py_tp_new, PyType_GenericNew}, + {Py_tp_init, pysqlite_cache_init}, + {0, NULL}, +}; + +static PyType_Spec pysqlite_CacheType_spec = { + .name = MODULE_NAME ".Cache", + .basicsize = sizeof(pysqlite_Cache), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE, + .slots = pysqlite_CacheType_slots, +}; +PyTypeObject *pysqlite_CacheType = NULL; + extern int pysqlite_cache_setup_types(void) { int rc; pysqlite_NodeType.tp_new = PyType_GenericNew; - pysqlite_CacheType.tp_new = PyType_GenericNew; rc = PyType_Ready(&pysqlite_NodeType); if (rc < 0) { return rc; } - rc = PyType_Ready(&pysqlite_CacheType); - return rc; + pysqlite_CacheType = (PyTypeObject *)PyType_FromSpec(&pysqlite_CacheType_spec); + if (pysqlite_CacheType == NULL) { + return -1; + } + return 0; } diff --git a/Modules/_sqlite/cache.h b/Modules/_sqlite/cache.h index 529010967c4f3a..0d4b4f1b34d9a2 100644 --- a/Modules/_sqlite/cache.h +++ b/Modules/_sqlite/cache.h @@ -60,7 +60,7 @@ typedef struct } pysqlite_Cache; extern PyTypeObject pysqlite_NodeType; -extern PyTypeObject pysqlite_CacheType; +extern PyTypeObject *pysqlite_CacheType; int pysqlite_node_init(pysqlite_Node* self, PyObject* args, PyObject* kwargs); void pysqlite_node_dealloc(pysqlite_Node* self); diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 81fc1335371a6f..121850ae7e1f32 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -133,7 +133,7 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject } Py_DECREF(isolation_level); - self->statement_cache = (pysqlite_Cache*)PyObject_CallFunction((PyObject*)&pysqlite_CacheType, "Oi", self, cached_statements); + self->statement_cache = (pysqlite_Cache*)PyObject_CallFunction((PyObject*)pysqlite_CacheType, "Oi", self, cached_statements); if (PyErr_Occurred()) { return -1; } From 00a62d96d54feda22ec5695d20e2fb75caf31d10 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 8 Sep 2020 22:30:26 +0200 Subject: [PATCH 2/8] Convert NodeType to heap type --- Modules/_sqlite/cache.c | 65 +++++++++++------------------------------ Modules/_sqlite/cache.h | 2 +- 2 files changed, 18 insertions(+), 49 deletions(-) diff --git a/Modules/_sqlite/cache.c b/Modules/_sqlite/cache.c index 229b34a4e25004..7b01ce1048ef0e 100644 --- a/Modules/_sqlite/cache.c +++ b/Modules/_sqlite/cache.c @@ -29,7 +29,7 @@ pysqlite_Node* pysqlite_new_node(PyObject* key, PyObject* data) { pysqlite_Node* node; - node = (pysqlite_Node*) (pysqlite_NodeType.tp_alloc(&pysqlite_NodeType, 0)); + node = (pysqlite_Node*) (pysqlite_NodeType->tp_alloc(pysqlite_NodeType, 0)); if (!node) { return NULL; } @@ -52,6 +52,7 @@ void pysqlite_node_dealloc(pysqlite_Node* self) Py_DECREF(self->data); Py_TYPE(self)->tp_free((PyObject*)self); + Py_DECREF(pysqlite_NodeType); } int pysqlite_cache_init(pysqlite_Cache* self, PyObject* args, PyObject* kwargs) @@ -254,47 +255,19 @@ PyObject* pysqlite_cache_display(pysqlite_Cache* self, PyObject* args) Py_RETURN_NONE; } -PyTypeObject pysqlite_NodeType = { - PyVarObject_HEAD_INIT(NULL, 0) - MODULE_NAME "Node", /* tp_name */ - sizeof(pysqlite_Node), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pysqlite_node_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0 /* tp_free */ +static PyType_Slot pysqlite_NodeType_slots[] = { + {Py_tp_dealloc, pysqlite_node_dealloc}, + {Py_tp_new, PyType_GenericNew}, + {0, NULL}, +}; + +PyType_Spec pysqlite_NodeType_spec = { + .name = MODULE_NAME ".Node", + .basicsize = sizeof(pysqlite_Node), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE, + .slots = pysqlite_NodeType_slots, }; +PyTypeObject *pysqlite_NodeType = NULL; static PyMethodDef cache_methods[] = { {"get", (PyCFunction)pysqlite_cache_get, METH_O, @@ -322,13 +295,9 @@ PyTypeObject *pysqlite_CacheType = NULL; extern int pysqlite_cache_setup_types(void) { - int rc; - - pysqlite_NodeType.tp_new = PyType_GenericNew; - - rc = PyType_Ready(&pysqlite_NodeType); - if (rc < 0) { - return rc; + pysqlite_NodeType = (PyTypeObject *)PyType_FromSpec(&pysqlite_NodeType_spec); + if (pysqlite_NodeType == NULL) { + return -1; } pysqlite_CacheType = (PyTypeObject *)PyType_FromSpec(&pysqlite_CacheType_spec); diff --git a/Modules/_sqlite/cache.h b/Modules/_sqlite/cache.h index 0d4b4f1b34d9a2..f141dd5a15d8fe 100644 --- a/Modules/_sqlite/cache.h +++ b/Modules/_sqlite/cache.h @@ -59,7 +59,7 @@ typedef struct int decref_factory; } pysqlite_Cache; -extern PyTypeObject pysqlite_NodeType; +extern PyTypeObject *pysqlite_NodeType; extern PyTypeObject *pysqlite_CacheType; int pysqlite_node_init(pysqlite_Node* self, PyObject* args, PyObject* kwargs); From 49393c76c243766ae9e88fb610dc95092b4212f2 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 8 Sep 2020 23:12:38 +0200 Subject: [PATCH 3/8] Convert StatementType to heap type --- Modules/_sqlite/connection.c | 2 +- Modules/_sqlite/cursor.c | 2 +- Modules/_sqlite/statement.c | 65 +++++++++++++----------------------- Modules/_sqlite/statement.h | 2 +- 4 files changed, 26 insertions(+), 45 deletions(-) diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 121850ae7e1f32..91e9046f50cb05 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -1234,7 +1234,7 @@ PyObject* pysqlite_connection_call(pysqlite_Connection* self, PyObject* args, Py _pysqlite_drop_unused_statement_references(self); - statement = PyObject_New(pysqlite_Statement, &pysqlite_StatementType); + statement = PyObject_New(pysqlite_Statement, pysqlite_StatementType); if (!statement) { return NULL; } diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 5cfb4b97d61dfe..dbbdb12caddd6d 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -472,7 +472,7 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* args) if (self->statement->in_use) { Py_SETREF(self->statement, - PyObject_New(pysqlite_Statement, &pysqlite_StatementType)); + PyObject_New(pysqlite_Statement, pysqlite_StatementType)); if (!self->statement) { goto error; } diff --git a/Modules/_sqlite/statement.c b/Modules/_sqlite/statement.c index 02e47a02b718cc..4ef9b10935ddf8 100644 --- a/Modules/_sqlite/statement.c +++ b/Modules/_sqlite/statement.c @@ -386,6 +386,7 @@ void pysqlite_statement_dealloc(pysqlite_Statement* self) } Py_TYPE(self)->tp_free((PyObject*)self); + Py_DECREF(pysqlite_StatementType); } /* @@ -458,50 +459,30 @@ static int pysqlite_check_remaining_sql(const char* tail) return 0; } -PyTypeObject pysqlite_StatementType = { - PyVarObject_HEAD_INIT(NULL, 0) - MODULE_NAME ".Statement", /* tp_name */ - sizeof(pysqlite_Statement), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pysqlite_statement_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(pysqlite_Statement, in_weakreflist), /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0 /* tp_free */ +static PyMemberDef pysqlite_StatementType_members[] = { + {"__weaklistoffset__", T_PYSSIZET, offsetof(pysqlite_Statement, in_weakreflist), READONLY}, + {NULL}, }; +static PyType_Slot pysqlite_StatementType_slots[] = { + {Py_tp_members, pysqlite_StatementType_members}, + {Py_tp_dealloc, pysqlite_statement_dealloc}, + {Py_tp_new, PyType_GenericNew}, + {0, NULL}, +}; + +PyType_Spec pysqlite_StatementType_spec = { + .name = MODULE_NAME ".Statement", + .basicsize = sizeof(pysqlite_Statement), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE, + .slots = pysqlite_StatementType_slots, +}; +PyTypeObject *pysqlite_StatementType = NULL; extern int pysqlite_statement_setup_types(void) { - pysqlite_StatementType.tp_new = PyType_GenericNew; - return PyType_Ready(&pysqlite_StatementType); + pysqlite_StatementType = (PyTypeObject *)PyType_FromSpec(&pysqlite_StatementType_spec); + if (pysqlite_StatementType == NULL) { + return -1; + } + return 0; } diff --git a/Modules/_sqlite/statement.h b/Modules/_sqlite/statement.h index 5002f02dc5b392..14ed1350d77cf1 100644 --- a/Modules/_sqlite/statement.h +++ b/Modules/_sqlite/statement.h @@ -43,7 +43,7 @@ typedef struct PyObject* in_weakreflist; /* List of weak references */ } pysqlite_Statement; -extern PyTypeObject pysqlite_StatementType; +extern PyTypeObject *pysqlite_StatementType; int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* connection, PyObject* sql); void pysqlite_statement_dealloc(pysqlite_Statement* self); From 55ad447daea193b548e4e70bc6a8b17bd41f23bc Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 8 Sep 2020 23:16:47 +0200 Subject: [PATCH 4/8] Convert RowType to heap type --- Modules/_sqlite/module.c | 2 +- Modules/_sqlite/row.c | 86 +++++++++++++--------------------------- Modules/_sqlite/row.h | 2 +- 3 files changed, 29 insertions(+), 61 deletions(-) diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c index 82f58eb2480261..82847d358f4bce 100644 --- a/Modules/_sqlite/module.c +++ b/Modules/_sqlite/module.c @@ -366,7 +366,7 @@ PyMODINIT_FUNC PyInit__sqlite3(void) ADD_TYPE(module, pysqlite_ConnectionType); ADD_TYPE(module, pysqlite_CursorType); ADD_TYPE(module, pysqlite_PrepareProtocolType); - ADD_TYPE(module, pysqlite_RowType); + ADD_TYPE(module, *pysqlite_RowType); if (!(dict = PyModule_GetDict(module))) { goto error; diff --git a/Modules/_sqlite/row.c b/Modules/_sqlite/row.c index 4b47108278a0ab..e6cdb0c0f0e3d6 100644 --- a/Modules/_sqlite/row.c +++ b/Modules/_sqlite/row.c @@ -30,6 +30,7 @@ void pysqlite_row_dealloc(pysqlite_Row* self) Py_XDECREF(self->description); Py_TYPE(self)->tp_free((PyObject*)self); + Py_DECREF(pysqlite_RowType); } static PyObject * @@ -192,7 +193,7 @@ static PyObject* pysqlite_row_richcompare(pysqlite_Row *self, PyObject *_other, if (opid != Py_EQ && opid != Py_NE) Py_RETURN_NOTIMPLEMENTED; - if (PyObject_TypeCheck(_other, &pysqlite_RowType)) { + if (PyObject_TypeCheck(_other, pysqlite_RowType)) { pysqlite_Row *other = (pysqlite_Row *)_other; int eq = PyObject_RichCompareBool(self->description, other->description, Py_EQ); if (eq < 0) { @@ -206,73 +207,40 @@ static PyObject* pysqlite_row_richcompare(pysqlite_Row *self, PyObject *_other, Py_RETURN_NOTIMPLEMENTED; } -PyMappingMethods pysqlite_row_as_mapping = { - /* mp_length */ (lenfunc)pysqlite_row_length, - /* mp_subscript */ (binaryfunc)pysqlite_row_subscript, - /* mp_ass_subscript */ (objobjargproc)0, -}; - -static PySequenceMethods pysqlite_row_as_sequence = { - /* sq_length */ (lenfunc)pysqlite_row_length, - /* sq_concat */ 0, - /* sq_repeat */ 0, - /* sq_item */ (ssizeargfunc)pysqlite_row_item, -}; - - static PyMethodDef pysqlite_row_methods[] = { {"keys", (PyCFunction)pysqlite_row_keys, METH_NOARGS, PyDoc_STR("Returns the keys of the row.")}, {NULL, NULL} }; +static PyType_Slot pysqlite_RowType_slots[] = { + {Py_tp_dealloc, pysqlite_row_dealloc}, + {Py_tp_hash, pysqlite_row_hash}, + {Py_tp_methods, pysqlite_row_methods}, + {Py_tp_richcompare, pysqlite_row_richcompare}, + {Py_tp_iter, pysqlite_iter}, + {Py_mp_length, pysqlite_row_length}, + {Py_mp_subscript, pysqlite_row_subscript}, + {Py_sq_length, pysqlite_row_length}, + {Py_sq_item, pysqlite_row_item}, + {Py_tp_new, pysqlite_row_new}, + {0, NULL}, +}; -PyTypeObject pysqlite_RowType = { - PyVarObject_HEAD_INIT(NULL, 0) - MODULE_NAME ".Row", /* tp_name */ - sizeof(pysqlite_Row), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pysqlite_row_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - (hashfunc)pysqlite_row_hash, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)0, /* tp_traverse */ - 0, /* tp_clear */ - (richcmpfunc)pysqlite_row_richcompare, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - (getiterfunc)pysqlite_iter, /* tp_iter */ - 0, /* tp_iternext */ - pysqlite_row_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0 /* tp_free */ +static PyType_Spec pysqlite_RowType_spec = { + .name = MODULE_NAME ".Row", + .basicsize = sizeof(pysqlite_Row), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE, + .slots = pysqlite_RowType_slots, }; +PyTypeObject *pysqlite_RowType = NULL; + extern int pysqlite_row_setup_types(void) { - pysqlite_RowType.tp_new = pysqlite_row_new; - pysqlite_RowType.tp_as_mapping = &pysqlite_row_as_mapping; - pysqlite_RowType.tp_as_sequence = &pysqlite_row_as_sequence; - return PyType_Ready(&pysqlite_RowType); + pysqlite_RowType = (PyTypeObject *)PyType_FromSpec(&pysqlite_RowType_spec); + if (pysqlite_RowType == NULL) { + return -1; + } + return 0; } diff --git a/Modules/_sqlite/row.h b/Modules/_sqlite/row.h index 4ad506f8dd9687..c454d16a95e6e7 100644 --- a/Modules/_sqlite/row.h +++ b/Modules/_sqlite/row.h @@ -33,7 +33,7 @@ typedef struct _Row PyObject* description; } pysqlite_Row; -extern PyTypeObject pysqlite_RowType; +extern PyTypeObject *pysqlite_RowType; int pysqlite_row_setup_types(void); From 914082ffab92661d3a92ea1c53665ac6c73eb003 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Sat, 6 Jun 2020 22:33:29 +0200 Subject: [PATCH 5/8] Convert PrepareProtocolType to heap type --- Modules/_sqlite/microprotocols.c | 4 +- Modules/_sqlite/module.c | 4 +- Modules/_sqlite/prepare_protocol.c | 62 +++++++++--------------------- Modules/_sqlite/prepare_protocol.h | 2 +- Modules/_sqlite/statement.c | 4 +- 5 files changed, 26 insertions(+), 50 deletions(-) diff --git a/Modules/_sqlite/microprotocols.c b/Modules/_sqlite/microprotocols.c index 3b2d7f42b87353..64095adb4db2b2 100644 --- a/Modules/_sqlite/microprotocols.c +++ b/Modules/_sqlite/microprotocols.c @@ -56,7 +56,7 @@ pysqlite_microprotocols_add(PyTypeObject *type, PyObject *proto, PyObject *cast) PyObject* key; int rc; - if (proto == NULL) proto = (PyObject*)&pysqlite_PrepareProtocolType; + if (proto == NULL) proto = (PyObject*)pysqlite_PrepareProtocolType; key = Py_BuildValue("(OO)", (PyObject*)type, proto); if (!key) { @@ -152,7 +152,7 @@ PyObject * pysqlite_adapt(pysqlite_Cursor *self, PyObject *args) { PyObject *obj, *alt = NULL; - PyObject *proto = (PyObject*)&pysqlite_PrepareProtocolType; + PyObject *proto = (PyObject*)pysqlite_PrepareProtocolType; if (!PyArg_ParseTuple(args, "O|OO", &obj, &proto, &alt)) return NULL; return pysqlite_microprotocols_adapt(obj, proto, alt); diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c index 82847d358f4bce..b559057c03103e 100644 --- a/Modules/_sqlite/module.c +++ b/Modules/_sqlite/module.c @@ -176,7 +176,7 @@ static PyObject* module_register_adapter(PyObject* self, PyObject* args) pysqlite_BaseTypeAdapted = 1; } - rc = pysqlite_microprotocols_add(type, (PyObject*)&pysqlite_PrepareProtocolType, caster); + rc = pysqlite_microprotocols_add(type, (PyObject*)pysqlite_PrepareProtocolType, caster); if (rc == -1) return NULL; @@ -365,7 +365,7 @@ PyMODINIT_FUNC PyInit__sqlite3(void) ADD_TYPE(module, pysqlite_ConnectionType); ADD_TYPE(module, pysqlite_CursorType); - ADD_TYPE(module, pysqlite_PrepareProtocolType); + ADD_TYPE(module, *pysqlite_PrepareProtocolType); ADD_TYPE(module, *pysqlite_RowType); if (!(dict = PyModule_GetDict(module))) { diff --git a/Modules/_sqlite/prepare_protocol.c b/Modules/_sqlite/prepare_protocol.c index 05a2ca5a652f5e..9866d31ad0b0b2 100644 --- a/Modules/_sqlite/prepare_protocol.c +++ b/Modules/_sqlite/prepare_protocol.c @@ -33,51 +33,27 @@ void pysqlite_prepare_protocol_dealloc(pysqlite_PrepareProtocol* self) Py_TYPE(self)->tp_free((PyObject*)self); } -PyTypeObject pysqlite_PrepareProtocolType= { - PyVarObject_HEAD_INIT(NULL, 0) - MODULE_NAME ".PrepareProtocol", /* tp_name */ - sizeof(pysqlite_PrepareProtocol), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pysqlite_prepare_protocol_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)pysqlite_prepare_protocol_init, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0 /* tp_free */ +static PyType_Slot pysqlite_PrepareProtocolType_slots[] = { + {Py_tp_dealloc, pysqlite_prepare_protocol_dealloc}, + {Py_tp_new, PyType_GenericNew}, + {Py_tp_init, pysqlite_prepare_protocol_init}, + {0, NULL}, }; +static PyType_Spec pysqlite_PrepareProtocolType_spec = { + .name = MODULE_NAME ".PrepareProtocol", + .basicsize = sizeof(pysqlite_PrepareProtocol), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE, + .slots = pysqlite_PrepareProtocolType_slots, +}; + +PyTypeObject *pysqlite_PrepareProtocolType = NULL; + extern int pysqlite_prepare_protocol_setup_types(void) { - pysqlite_PrepareProtocolType.tp_new = PyType_GenericNew; - Py_SET_TYPE(&pysqlite_PrepareProtocolType, &PyType_Type); - return PyType_Ready(&pysqlite_PrepareProtocolType); + pysqlite_PrepareProtocolType = (PyTypeObject *)PyType_FromSpec(&pysqlite_PrepareProtocolType_spec); + if (pysqlite_PrepareProtocolType == NULL) { + return -1; + } + return 0; } diff --git a/Modules/_sqlite/prepare_protocol.h b/Modules/_sqlite/prepare_protocol.h index 3998a55e51cafe..5b1d3b9190dd3b 100644 --- a/Modules/_sqlite/prepare_protocol.h +++ b/Modules/_sqlite/prepare_protocol.h @@ -31,7 +31,7 @@ typedef struct PyObject_HEAD } pysqlite_PrepareProtocol; -extern PyTypeObject pysqlite_PrepareProtocolType; +extern PyTypeObject *pysqlite_PrepareProtocolType; int pysqlite_prepare_protocol_init(pysqlite_PrepareProtocol* self, PyObject* args, PyObject* kwargs); void pysqlite_prepare_protocol_dealloc(pysqlite_PrepareProtocol* self); diff --git a/Modules/_sqlite/statement.c b/Modules/_sqlite/statement.c index 4ef9b10935ddf8..138e844a3f81cd 100644 --- a/Modules/_sqlite/statement.c +++ b/Modules/_sqlite/statement.c @@ -255,7 +255,7 @@ void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* para if (!_need_adapt(current_param)) { adapted = current_param; } else { - adapted = pysqlite_microprotocols_adapt(current_param, (PyObject*)&pysqlite_PrepareProtocolType, current_param); + adapted = pysqlite_microprotocols_adapt(current_param, (PyObject*)pysqlite_PrepareProtocolType, current_param); Py_DECREF(current_param); if (!adapted) { return; @@ -306,7 +306,7 @@ void pysqlite_statement_bind_parameters(pysqlite_Statement* self, PyObject* para if (!_need_adapt(current_param)) { adapted = current_param; } else { - adapted = pysqlite_microprotocols_adapt(current_param, (PyObject*)&pysqlite_PrepareProtocolType, current_param); + adapted = pysqlite_microprotocols_adapt(current_param, (PyObject*)pysqlite_PrepareProtocolType, current_param); Py_DECREF(current_param); if (!adapted) { return; From 502d2fb5aff45840d79962128a28d2df8fe1ffbf Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Fri, 25 Sep 2020 14:12:19 +0200 Subject: [PATCH 6/8] Convert CursorType to head type FIXME: leaks refs --- Modules/_sqlite/connection.c | 4 +- Modules/_sqlite/cursor.c | 67 +++++++++++------------------- Modules/_sqlite/cursor.h | 2 +- Modules/_sqlite/module.c | 2 +- Modules/_sqlite/prepare_protocol.c | 1 + Modules/_sqlite/row.c | 2 +- 6 files changed, 31 insertions(+), 47 deletions(-) diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 91e9046f50cb05..a6eb0c45ac8509 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -281,13 +281,13 @@ PyObject* pysqlite_connection_cursor(pysqlite_Connection* self, PyObject* args, } if (factory == NULL) { - factory = (PyObject*)&pysqlite_CursorType; + factory = (PyObject*)pysqlite_CursorType; } cursor = PyObject_CallOneArg(factory, (PyObject *)self); if (cursor == NULL) return NULL; - if (!PyObject_TypeCheck(cursor, &pysqlite_CursorType)) { + if (!PyObject_TypeCheck(cursor, pysqlite_CursorType)) { PyErr_Format(PyExc_TypeError, "factory must return a cursor, not %.100s", Py_TYPE(cursor)->tp_name); diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index dbbdb12caddd6d..fa032c20689a0c 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -898,56 +898,39 @@ static struct PyMemberDef cursor_members[] = {"lastrowid", T_OBJECT, offsetof(pysqlite_Cursor, lastrowid), READONLY}, {"rowcount", T_LONG, offsetof(pysqlite_Cursor, rowcount), READONLY}, {"row_factory", T_OBJECT, offsetof(pysqlite_Cursor, row_factory), 0}, + {"__weaklistoffset__", T_PYSSIZET, offsetof(pysqlite_Cursor, in_weakreflist), READONLY}, {NULL} }; static const char cursor_doc[] = PyDoc_STR("SQLite database cursor class."); -PyTypeObject pysqlite_CursorType = { - PyVarObject_HEAD_INIT(NULL, 0) - MODULE_NAME ".Cursor", /* tp_name */ - sizeof(pysqlite_Cursor), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pysqlite_cursor_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */ - cursor_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(pysqlite_Cursor, in_weakreflist), /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)pysqlite_cursor_iternext, /* tp_iternext */ - cursor_methods, /* tp_methods */ - cursor_members, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)pysqlite_cursor_init, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0 /* tp_free */ +PyType_Slot pysqlite_CursorType_slots[] = { + {Py_tp_dealloc, pysqlite_cursor_dealloc}, + {Py_tp_doc, (void *)cursor_doc}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, pysqlite_cursor_iternext}, + {Py_tp_methods, cursor_methods}, + {Py_tp_members, cursor_members}, + {Py_tp_new, PyType_GenericNew}, + {Py_tp_init, pysqlite_cursor_init}, + {0, NULL}, }; +PyType_Spec pysqlite_CursorType_spec = { + .name = MODULE_NAME ".Cursor", + .basicsize = sizeof(pysqlite_Cursor), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE, + .slots = pysqlite_CursorType_slots, +}; + +PyTypeObject *pysqlite_CursorType = NULL; + extern int pysqlite_cursor_setup_types(void) { - pysqlite_CursorType.tp_new = PyType_GenericNew; - return PyType_Ready(&pysqlite_CursorType); + pysqlite_CursorType = (PyTypeObject *)PyType_FromSpec(&pysqlite_CursorType_spec); + if (pysqlite_CursorType == NULL) { + return -1; + } + return 0; } diff --git a/Modules/_sqlite/cursor.h b/Modules/_sqlite/cursor.h index 4a20e756f7829d..f3aeaa05446652 100644 --- a/Modules/_sqlite/cursor.h +++ b/Modules/_sqlite/cursor.h @@ -52,7 +52,7 @@ typedef struct PyObject* in_weakreflist; /* List of weak references */ } pysqlite_Cursor; -extern PyTypeObject pysqlite_CursorType; +extern PyTypeObject *pysqlite_CursorType; PyObject* pysqlite_cursor_execute(pysqlite_Cursor* self, PyObject* args); PyObject* pysqlite_cursor_executemany(pysqlite_Cursor* self, PyObject* args); diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c index b559057c03103e..f0e1756ca4b4a9 100644 --- a/Modules/_sqlite/module.c +++ b/Modules/_sqlite/module.c @@ -364,7 +364,7 @@ PyMODINIT_FUNC PyInit__sqlite3(void) } ADD_TYPE(module, pysqlite_ConnectionType); - ADD_TYPE(module, pysqlite_CursorType); + ADD_TYPE(module, *pysqlite_CursorType); ADD_TYPE(module, *pysqlite_PrepareProtocolType); ADD_TYPE(module, *pysqlite_RowType); diff --git a/Modules/_sqlite/prepare_protocol.c b/Modules/_sqlite/prepare_protocol.c index 9866d31ad0b0b2..3aaf4efe7d5e5a 100644 --- a/Modules/_sqlite/prepare_protocol.c +++ b/Modules/_sqlite/prepare_protocol.c @@ -31,6 +31,7 @@ int pysqlite_prepare_protocol_init(pysqlite_PrepareProtocol* self, PyObject* arg void pysqlite_prepare_protocol_dealloc(pysqlite_PrepareProtocol* self) { Py_TYPE(self)->tp_free((PyObject*)self); + Py_DECREF(pysqlite_PrepareProtocolType); } static PyType_Slot pysqlite_PrepareProtocolType_slots[] = { diff --git a/Modules/_sqlite/row.c b/Modules/_sqlite/row.c index e6cdb0c0f0e3d6..43b39a5bd0aa16 100644 --- a/Modules/_sqlite/row.c +++ b/Modules/_sqlite/row.c @@ -47,7 +47,7 @@ pysqlite_row_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) if (!PyArg_ParseTuple(args, "OO", &cursor, &data)) return NULL; - if (!PyObject_TypeCheck((PyObject*)cursor, &pysqlite_CursorType)) { + if (!PyObject_TypeCheck((PyObject*)cursor, pysqlite_CursorType)) { PyErr_SetString(PyExc_TypeError, "instance of cursor required for first argument"); return NULL; } From e6f935dac8dde362a066813945d5e0bacb18b206 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 8 Sep 2020 23:50:40 +0200 Subject: [PATCH 7/8] Convert ConnectionType to heap type FIXME: Leaks refs --- Modules/_sqlite/connection.c | 68 +++++++++++++----------------------- Modules/_sqlite/connection.h | 2 +- Modules/_sqlite/cursor.c | 2 +- Modules/_sqlite/module.c | 2 +- 4 files changed, 28 insertions(+), 46 deletions(-) diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index a6eb0c45ac8509..8a3914fdb71b46 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -237,6 +237,7 @@ void pysqlite_connection_dealloc(pysqlite_Connection* self) Py_XDECREF(self->statements); Py_XDECREF(self->cursors); Py_TYPE(self)->tp_free((PyObject*)self); + //Py_DECREF(pysqlite_ConnectionType); FIXME } /* @@ -1494,7 +1495,7 @@ pysqlite_connection_backup(pysqlite_Connection *self, PyObject *args, PyObject * static char *keywords[] = {"target", "pages", "progress", "name", "sleep", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|$iOsO:backup", keywords, - &pysqlite_ConnectionType, &target, + pysqlite_ConnectionType, &target, &pages, &progress, &name, &sleep_obj)) { return NULL; } @@ -1831,50 +1832,31 @@ static struct PyMemberDef connection_members[] = {NULL} }; -PyTypeObject pysqlite_ConnectionType = { - PyVarObject_HEAD_INIT(NULL, 0) - MODULE_NAME ".Connection", /* tp_name */ - sizeof(pysqlite_Connection), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pysqlite_connection_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - (ternaryfunc)pysqlite_connection_call, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */ - connection_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - connection_methods, /* tp_methods */ - connection_members, /* tp_members */ - connection_getset, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)pysqlite_connection_init, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0 /* tp_free */ +static PyType_Slot pysqlite_ConnectionType_slots[] = { + {Py_tp_dealloc, pysqlite_connection_dealloc}, + {Py_tp_doc, (void *)connection_doc}, + {Py_tp_methods, connection_methods}, + {Py_tp_members, connection_members}, + {Py_tp_getset, connection_getset}, + {Py_tp_new, PyType_GenericNew}, + {Py_tp_init, pysqlite_connection_init}, + {Py_tp_call, pysqlite_connection_call}, + {0, NULL}, }; +static PyType_Spec pysqlite_ConnectionType_spec = { + .name = MODULE_NAME ".Connection", + .basicsize = sizeof(pysqlite_Connection), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE, + .slots = pysqlite_ConnectionType_slots, +}; +PyTypeObject *pysqlite_ConnectionType = NULL; + extern int pysqlite_connection_setup_types(void) { - pysqlite_ConnectionType.tp_new = PyType_GenericNew; - return PyType_Ready(&pysqlite_ConnectionType); + pysqlite_ConnectionType = (PyTypeObject *)PyType_FromSpec(&pysqlite_ConnectionType_spec); + if (pysqlite_ConnectionType == NULL) { + return -1; + } + return 0; } diff --git a/Modules/_sqlite/connection.h b/Modules/_sqlite/connection.h index 206085e00a00c7..4a3faea47b7299 100644 --- a/Modules/_sqlite/connection.h +++ b/Modules/_sqlite/connection.h @@ -106,7 +106,7 @@ typedef struct PyObject* NotSupportedError; } pysqlite_Connection; -extern PyTypeObject pysqlite_ConnectionType; +extern PyTypeObject *pysqlite_ConnectionType; PyObject* pysqlite_connection_alloc(PyTypeObject* type, int aware); void pysqlite_connection_dealloc(pysqlite_Connection* self); diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index fa032c20689a0c..290b34a2bf2736 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -33,7 +33,7 @@ static int pysqlite_cursor_init(pysqlite_Cursor* self, PyObject* args, PyObject* { pysqlite_Connection* connection; - if (!PyArg_ParseTuple(args, "O!", &pysqlite_ConnectionType, &connection)) + if (!PyArg_ParseTuple(args, "O!", pysqlite_ConnectionType, &connection)) { return -1; } diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c index f0e1756ca4b4a9..960ebbd1325e14 100644 --- a/Modules/_sqlite/module.c +++ b/Modules/_sqlite/module.c @@ -82,7 +82,7 @@ static PyObject* module_connect(PyObject* self, PyObject* args, PyObject* } if (factory == NULL) { - factory = (PyObject*)&pysqlite_ConnectionType; + factory = (PyObject*)pysqlite_ConnectionType; } if (PySys_Audit("sqlite3.connect", "O", database) < 0) { From 812fc4f29c8918ede81c0176f3c6228d34278d26 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Fri, 25 Sep 2020 14:35:25 +0200 Subject: [PATCH 8/8] Add NEWS entry --- .../NEWS.d/next/Library/2020-09-25-14-34-08.bpo-41861.YTqJ7z.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2020-09-25-14-34-08.bpo-41861.YTqJ7z.rst diff --git a/Misc/NEWS.d/next/Library/2020-09-25-14-34-08.bpo-41861.YTqJ7z.rst b/Misc/NEWS.d/next/Library/2020-09-25-14-34-08.bpo-41861.YTqJ7z.rst new file mode 100644 index 00000000000000..c0eda7b568bb9b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-09-25-14-34-08.bpo-41861.YTqJ7z.rst @@ -0,0 +1 @@ +Convert :mod:`sqlite3` to PEP 384.