summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/sqlite3/test/dbapi.py21
-rw-r--r--Modules/_sqlite/connection.c29
2 files changed, 43 insertions, 7 deletions
diff --git a/Lib/sqlite3/test/dbapi.py b/Lib/sqlite3/test/dbapi.py
index a958d4d..2d02045 100644
--- a/Lib/sqlite3/test/dbapi.py
+++ b/Lib/sqlite3/test/dbapi.py
@@ -197,6 +197,26 @@ class ConnectionTests(unittest.TestCase):
cx.execute('insert into test(id) values(1)')
+class UninitialisedConnectionTests(unittest.TestCase):
+ def setUp(self):
+ self.cx = sqlite.Connection.__new__(sqlite.Connection)
+
+ def test_uninit_operations(self):
+ funcs = (
+ lambda: self.cx.isolation_level,
+ lambda: self.cx.total_changes,
+ lambda: self.cx.in_transaction,
+ lambda: self.cx.iterdump(),
+ lambda: self.cx.cursor(),
+ lambda: self.cx.close(),
+ )
+ for func in funcs:
+ with self.subTest(func=func):
+ self.assertRaisesRegex(sqlite.ProgrammingError,
+ "Base Connection.__init__ not called",
+ func)
+
+
class CursorTests(unittest.TestCase):
def setUp(self):
self.cx = sqlite.connect(":memory:")
@@ -949,6 +969,7 @@ def suite():
ModuleTests,
SqliteOnConflictTests,
ThreadTests,
+ UninitialisedConnectionTests,
]
return unittest.TestSuite(
[unittest.TestLoader().loadTestsFromTestCase(t) for t in tests]
diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c
index 95f6029..9c05a15 100644
--- a/Modules/_sqlite/connection.c
+++ b/Modules/_sqlite/connection.c
@@ -92,8 +92,6 @@ pysqlite_connection_init(pysqlite_Connection *self, PyObject *args,
database = PyBytes_AsString(database_obj);
- self->initialized = 1;
-
self->begin_statement = NULL;
Py_CLEAR(self->statement_cache);
@@ -128,7 +126,7 @@ pysqlite_connection_init(pysqlite_Connection *self, PyObject *args,
Py_INCREF(isolation_level);
}
Py_CLEAR(self->isolation_level);
- if (pysqlite_connection_set_isolation_level(self, isolation_level, NULL) < 0) {
+ if (pysqlite_connection_set_isolation_level(self, isolation_level, NULL) != 0) {
Py_DECREF(isolation_level);
return -1;
}
@@ -187,6 +185,8 @@ pysqlite_connection_init(pysqlite_Connection *self, PyObject *args,
return -1;
}
+ self->initialized = 1;
+
return 0;
}
@@ -359,6 +359,12 @@ pysqlite_connection_close_impl(pysqlite_Connection *self)
return NULL;
}
+ if (!self->initialized) {
+ PyErr_SetString(pysqlite_ProgrammingError,
+ "Base Connection.__init__ not called.");
+ return NULL;
+ }
+
pysqlite_do_all_statements(self, ACTION_FINALIZE, 1);
if (self->db) {
@@ -1264,6 +1270,9 @@ int pysqlite_check_thread(pysqlite_Connection* self)
static PyObject* pysqlite_connection_get_isolation_level(pysqlite_Connection* self, void* unused)
{
+ if (!pysqlite_check_connection(self)) {
+ return NULL;
+ }
return Py_NewRef(self->isolation_level);
}
@@ -1295,11 +1304,17 @@ pysqlite_connection_set_isolation_level(pysqlite_Connection* self, PyObject* iso
return -1;
}
if (isolation_level == Py_None) {
- PyObject *res = pysqlite_connection_commit(self, NULL);
- if (!res) {
- return -1;
+ /* We might get called during connection init, so we cannot use
+ * pysqlite_connection_commit() here. */
+ if (self->db && !sqlite3_get_autocommit(self->db)) {
+ int rc;
+ Py_BEGIN_ALLOW_THREADS
+ rc = sqlite3_exec(self->db, "COMMIT", NULL, NULL, NULL);
+ Py_END_ALLOW_THREADS
+ if (rc != SQLITE_OK) {
+ return _pysqlite_seterror(self->db, NULL);
+ }
}
- Py_DECREF(res);
self->begin_statement = NULL;
} else {