bpo-41861: Convert _sqlite3 RowType and StatementType to heap types (GH-22444)

diff --git a/Modules/_sqlite/row.c b/Modules/_sqlite/row.c
index 4b47108..85179e7 100644
--- a/Modules/_sqlite/row.c
+++ b/Modules/_sqlite/row.c
@@ -26,10 +26,13 @@
 
 void pysqlite_row_dealloc(pysqlite_Row* self)
 {
+    PyTypeObject *tp = Py_TYPE(self);
+
     Py_XDECREF(self->data);
     Py_XDECREF(self->description);
 
-    Py_TYPE(self)->tp_free((PyObject*)self);
+    tp->tp_free(self);
+    Py_DECREF(tp);
 }
 
 static PyObject *
@@ -192,7 +195,7 @@
     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 +209,40 @@
     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[] = {
+static PyMethodDef row_methods[] = {
     {"keys", (PyCFunction)pysqlite_row_keys, METH_NOARGS,
         PyDoc_STR("Returns the keys of the row.")},
     {NULL, 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_Slot row_slots[] = {
+    {Py_tp_dealloc, pysqlite_row_dealloc},
+    {Py_tp_hash, pysqlite_row_hash},
+    {Py_tp_methods, 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},
 };
 
-extern int pysqlite_row_setup_types(void)
+static PyType_Spec row_spec = {
+    .name = MODULE_NAME ".Row",
+    .basicsize = sizeof(pysqlite_Row),
+    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+    .slots = row_slots,
+};
+
+PyTypeObject *pysqlite_RowType = NULL;
+
+extern int pysqlite_row_setup_types(PyObject *module)
 {
-    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_FromModuleAndSpec(module, &row_spec, NULL);
+    if (pysqlite_RowType == NULL) {
+        return -1;
+    }
+    return 0;
 }