Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bpo-41861: Convert _sqlite3 CursorType and ConnectionType to heap types #22478

Merged
merged 2 commits into from
Oct 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 33 additions & 47 deletions Modules/_sqlite/connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,8 @@ void pysqlite_do_all_statements(pysqlite_Connection* self, int action, int reset

void pysqlite_connection_dealloc(pysqlite_Connection* self)
{
PyTypeObject *tp = Py_TYPE(self);

Py_XDECREF(self->statement_cache);

/* Clean up if user has not called .close() explicitly. */
Expand All @@ -236,7 +238,9 @@ void pysqlite_connection_dealloc(pysqlite_Connection* self)
Py_XDECREF(self->collations);
Py_XDECREF(self->statements);
Py_XDECREF(self->cursors);
Py_TYPE(self)->tp_free((PyObject*)self);

tp->tp_free(self);
Py_DECREF(tp);
}

/*
Expand Down Expand Up @@ -281,13 +285,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);
Expand Down Expand Up @@ -1494,7 +1498,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;
}
Expand Down Expand Up @@ -1831,50 +1835,32 @@ 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 connection_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 connection_spec = {
.name = MODULE_NAME ".Connection",
.basicsize = sizeof(pysqlite_Connection),
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
.slots = connection_slots,
};

extern int pysqlite_connection_setup_types(void)
PyTypeObject *pysqlite_ConnectionType = NULL;

extern int pysqlite_connection_setup_types(PyObject *module)
{
pysqlite_ConnectionType.tp_new = PyType_GenericNew;
return PyType_Ready(&pysqlite_ConnectionType);
pysqlite_ConnectionType = (PyTypeObject *)PyType_FromModuleAndSpec(module, &connection_spec, NULL);
if (pysqlite_ConnectionType == NULL) {
return -1;
}
return 0;
}
4 changes: 2 additions & 2 deletions Modules/_sqlite/connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -122,6 +122,6 @@ int pysqlite_connection_register_cursor(pysqlite_Connection* connection, PyObjec
int pysqlite_check_thread(pysqlite_Connection* self);
int pysqlite_check_connection(pysqlite_Connection* con);

int pysqlite_connection_setup_types(void);
int pysqlite_connection_setup_types(PyObject *module);

#endif
76 changes: 31 additions & 45 deletions Modules/_sqlite/cursor.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -74,6 +74,8 @@ static int pysqlite_cursor_init(pysqlite_Cursor* self, PyObject* args, PyObject*

static void pysqlite_cursor_dealloc(pysqlite_Cursor* self)
{
PyTypeObject *tp = Py_TYPE(self);

/* Reset the statement if the user has not closed the cursor */
if (self->statement) {
pysqlite_statement_reset(self->statement);
Expand All @@ -91,7 +93,8 @@ static void pysqlite_cursor_dealloc(pysqlite_Cursor* self)
PyObject_ClearWeakRefs((PyObject*)self);
}

Py_TYPE(self)->tp_free((PyObject*)self);
tp->tp_free(self);
Py_DECREF(tp);
}

static PyObject *
Expand Down Expand Up @@ -898,56 +901,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 */
static PyType_Slot cursor_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},
};

static PyType_Spec cursor_spec = {
.name = MODULE_NAME ".Cursor",
.basicsize = sizeof(pysqlite_Cursor),
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
.slots = cursor_slots,
};

extern int pysqlite_cursor_setup_types(void)
PyTypeObject *pysqlite_CursorType = NULL;

extern int pysqlite_cursor_setup_types(PyObject *module)
{
pysqlite_CursorType.tp_new = PyType_GenericNew;
return PyType_Ready(&pysqlite_CursorType);
pysqlite_CursorType = (PyTypeObject *)PyType_FromModuleAndSpec(module, &cursor_spec, NULL);
if (pysqlite_CursorType == NULL) {
return -1;
}
return 0;
}
4 changes: 2 additions & 2 deletions Modules/_sqlite/cursor.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -64,7 +64,7 @@ PyObject* pysqlite_cursor_fetchall(pysqlite_Cursor* self, PyObject* args);
PyObject* pysqlite_noop(pysqlite_Connection* self, PyObject* args);
PyObject* pysqlite_cursor_close(pysqlite_Cursor* self, PyObject* args);

int pysqlite_cursor_setup_types(void);
int pysqlite_cursor_setup_types(PyObject *module);

#define UNKNOWN (-1)
#endif
10 changes: 5 additions & 5 deletions Modules/_sqlite/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -353,8 +353,8 @@ PyMODINIT_FUNC PyInit__sqlite3(void)

if (!module ||
(pysqlite_row_setup_types(module) < 0) ||
(pysqlite_cursor_setup_types() < 0) ||
(pysqlite_connection_setup_types() < 0) ||
(pysqlite_cursor_setup_types(module) < 0) ||
(pysqlite_connection_setup_types(module) < 0) ||
(pysqlite_cache_setup_types(module) < 0) ||
(pysqlite_statement_setup_types(module) < 0) ||
(pysqlite_prepare_protocol_setup_types(module) < 0)
Expand All @@ -363,8 +363,8 @@ PyMODINIT_FUNC PyInit__sqlite3(void)
return NULL;
}

ADD_TYPE(module, pysqlite_ConnectionType);
ADD_TYPE(module, pysqlite_CursorType);
ADD_TYPE(module, *pysqlite_ConnectionType);
ADD_TYPE(module, *pysqlite_CursorType);
ADD_TYPE(module, *pysqlite_PrepareProtocolType);
ADD_TYPE(module, *pysqlite_RowType);

Expand Down
2 changes: 1 addition & 1 deletion Modules/_sqlite/row.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,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;
}
Expand Down