From b3af287affc6e8d8bbf0caf451eb48489de6f614 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 c3cedc5bf17c029d75facc9b5f0479826c9d9321 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 a3e33bdffb20849eb044a36b652c47ccf1c73ad2 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Sat, 26 Sep 2020 12:16:37 +0200 Subject: [PATCH 3/8] Add NEWS entry --- .../NEWS.d/next/Library/2020-09-26-12-16-28.bpo-41861.3xTsIp.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2020-09-26-12-16-28.bpo-41861.3xTsIp.rst diff --git a/Misc/NEWS.d/next/Library/2020-09-26-12-16-28.bpo-41861.3xTsIp.rst b/Misc/NEWS.d/next/Library/2020-09-26-12-16-28.bpo-41861.3xTsIp.rst new file mode 100644 index 00000000000000..690f702baee967 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-09-26-12-16-28.bpo-41861.3xTsIp.rst @@ -0,0 +1 @@ +Covert :mod:`sqlite3` Cache and Node types to heap types (PEP 384). From f1568b1ea971dfbe04a8ccf9b6072ec116f47e7c Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Sat, 26 Sep 2020 12:54:15 +0200 Subject: [PATCH 4/8] Revert "Add NEWS entry" This reverts commit a3e33bdffb20849eb044a36b652c47ccf1c73ad2. --- .../NEWS.d/next/Library/2020-09-26-12-16-28.bpo-41861.3xTsIp.rst | 1 - 1 file changed, 1 deletion(-) delete mode 100644 Misc/NEWS.d/next/Library/2020-09-26-12-16-28.bpo-41861.3xTsIp.rst diff --git a/Misc/NEWS.d/next/Library/2020-09-26-12-16-28.bpo-41861.3xTsIp.rst b/Misc/NEWS.d/next/Library/2020-09-26-12-16-28.bpo-41861.3xTsIp.rst deleted file mode 100644 index 690f702baee967..00000000000000 --- a/Misc/NEWS.d/next/Library/2020-09-26-12-16-28.bpo-41861.3xTsIp.rst +++ /dev/null @@ -1 +0,0 @@ -Covert :mod:`sqlite3` Cache and Node types to heap types (PEP 384). From cdb6e4c6ee49a4c18a36734428ba9fe244d1fbc5 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Sat, 26 Sep 2020 13:03:39 +0200 Subject: [PATCH 5/8] Use PyType_FromModuleAndSpec iso. PyType_FromSpec --- Modules/_sqlite/cache.c | 6 +++--- Modules/_sqlite/cache.h | 2 +- Modules/_sqlite/module.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Modules/_sqlite/cache.c b/Modules/_sqlite/cache.c index 7b01ce1048ef0e..74b30d19527c56 100644 --- a/Modules/_sqlite/cache.c +++ b/Modules/_sqlite/cache.c @@ -293,14 +293,14 @@ static PyType_Spec pysqlite_CacheType_spec = { }; PyTypeObject *pysqlite_CacheType = NULL; -extern int pysqlite_cache_setup_types(void) +extern int pysqlite_cache_setup_types(PyObject *mod) { - pysqlite_NodeType = (PyTypeObject *)PyType_FromSpec(&pysqlite_NodeType_spec); + pysqlite_NodeType = (PyTypeObject *)PyType_FromModuleAndSpec(mod, &pysqlite_NodeType_spec, NULL); if (pysqlite_NodeType == NULL) { return -1; } - pysqlite_CacheType = (PyTypeObject *)PyType_FromSpec(&pysqlite_CacheType_spec); + pysqlite_CacheType = (PyTypeObject *)PyType_FromModuleAndSpec(mod, &pysqlite_CacheType_spec, NULL); if (pysqlite_CacheType == NULL) { return -1; } diff --git a/Modules/_sqlite/cache.h b/Modules/_sqlite/cache.h index f141dd5a15d8fe..0afdf7f09b65c7 100644 --- a/Modules/_sqlite/cache.h +++ b/Modules/_sqlite/cache.h @@ -69,6 +69,6 @@ int pysqlite_cache_init(pysqlite_Cache* self, PyObject* args, PyObject* kwargs); void pysqlite_cache_dealloc(pysqlite_Cache* self); PyObject* pysqlite_cache_get(pysqlite_Cache* self, PyObject* args); -int pysqlite_cache_setup_types(void); +int pysqlite_cache_setup_types(PyObject *module); #endif diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c index 82f58eb2480261..625d065a317bab 100644 --- a/Modules/_sqlite/module.c +++ b/Modules/_sqlite/module.c @@ -355,7 +355,7 @@ PyMODINIT_FUNC PyInit__sqlite3(void) (pysqlite_row_setup_types() < 0) || (pysqlite_cursor_setup_types() < 0) || (pysqlite_connection_setup_types() < 0) || - (pysqlite_cache_setup_types() < 0) || + (pysqlite_cache_setup_types(module) < 0) || (pysqlite_statement_setup_types() < 0) || (pysqlite_prepare_protocol_setup_types() < 0) ) { From 6be8abc2a8e6fabeffe29d16ef0fb78e154be61d Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Sat, 26 Sep 2020 13:05:15 +0200 Subject: [PATCH 6/8] Improve dealloc --- Modules/_sqlite/cache.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Modules/_sqlite/cache.c b/Modules/_sqlite/cache.c index 74b30d19527c56..08e3755d542a3d 100644 --- a/Modules/_sqlite/cache.c +++ b/Modules/_sqlite/cache.c @@ -48,11 +48,13 @@ pysqlite_Node* pysqlite_new_node(PyObject* key, PyObject* data) void pysqlite_node_dealloc(pysqlite_Node* self) { + PyTypeObject *tp = Py_TYPE(self); + Py_DECREF(self->key); Py_DECREF(self->data); - Py_TYPE(self)->tp_free((PyObject*)self); - Py_DECREF(pysqlite_NodeType); + tp->tp_free(self); + Py_DECREF(tp); } int pysqlite_cache_init(pysqlite_Cache* self, PyObject* args, PyObject* kwargs) From fad7260d3c5735c63af1df80ae6f15ed2b8b530c Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Sat, 26 Sep 2020 13:36:39 +0200 Subject: [PATCH 7/8] Fix dealloc for cache type as well --- Modules/_sqlite/cache.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Modules/_sqlite/cache.c b/Modules/_sqlite/cache.c index 08e3755d542a3d..3e00e277fd6b90 100644 --- a/Modules/_sqlite/cache.c +++ b/Modules/_sqlite/cache.c @@ -91,6 +91,7 @@ int pysqlite_cache_init(pysqlite_Cache* self, PyObject* args, PyObject* kwargs) void pysqlite_cache_dealloc(pysqlite_Cache* self) { + PyTypeObject *tp = Py_TYPE(self); pysqlite_Node* node; pysqlite_Node* delete_node; @@ -112,8 +113,8 @@ void pysqlite_cache_dealloc(pysqlite_Cache* self) } Py_DECREF(self->mapping); - Py_TYPE(self)->tp_free((PyObject*)self); - Py_DECREF(pysqlite_CacheType); + tp->tp_free(self); + Py_DECREF(tp); } PyObject* pysqlite_cache_get(pysqlite_Cache* self, PyObject* key) From e8be010a2dcfbe775da053bbd6027695b27f098c Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Sat, 26 Sep 2020 13:51:29 +0200 Subject: [PATCH 8/8] Make node type spec static --- Modules/_sqlite/cache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/_sqlite/cache.c b/Modules/_sqlite/cache.c index 3e00e277fd6b90..c417ce872d368d 100644 --- a/Modules/_sqlite/cache.c +++ b/Modules/_sqlite/cache.c @@ -264,7 +264,7 @@ static PyType_Slot pysqlite_NodeType_slots[] = { {0, NULL}, }; -PyType_Spec pysqlite_NodeType_spec = { +static PyType_Spec pysqlite_NodeType_spec = { .name = MODULE_NAME ".Node", .basicsize = sizeof(pysqlite_Node), .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE,