diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 950df60b202..5f9a26a7bb1 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -19,7 +19,7 @@ PostgreSQL or Oracle. The sqlite3 module was written by Gerhard Häring. It provides a SQL interface compliant with the DB-API 2.0 specification described by :pep:`249`, and -requires SQLite 3.7.3 or newer. +requires SQLite 3.7.15 or newer. To use the module, you must first create a :class:`Connection` object that represents the database. Here the data will be stored in the diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index 4181eba81cf..444f1326e5b 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -577,13 +577,12 @@ CPython bytecode changes Build Changes ============= - * The C99 functions :c:func:`snprintf` and :c:func:`vsnprintf` are now required to build Python. (Contributed by Victor Stinner in :issue:`36020`.) -* :mod:`sqlite3` requires SQLite 3.7.3 or higher. - (Contributed by Sergey Fedoseev and Erlend E. Aasland :issue:`40744`.) +* :mod:`sqlite3` requires SQLite 3.7.15 or higher. (Contributed by Sergey Fedoseev + and Erlend E. Aasland :issue:`40744` and :issue:`40810`.) * The :mod:`atexit` module must now always be built as a built-in module. (Contributed by Victor Stinner in :issue:`42639`.) diff --git a/Lib/sqlite3/test/dbapi.py b/Lib/sqlite3/test/dbapi.py index 7867bf361e5..2b85ef99f02 100644 --- a/Lib/sqlite3/test/dbapi.py +++ b/Lib/sqlite3/test/dbapi.py @@ -172,10 +172,6 @@ class ConnectionTests(unittest.TestCase): cx.execute('create table test(id integer)') def CheckOpenUri(self): - if sqlite.sqlite_version_info < (3, 7, 7): - with self.assertRaises(sqlite.NotSupportedError): - sqlite.connect(':memory:', uri=True) - return self.addCleanup(unlink, TESTFN) with sqlite.connect(TESTFN) as cx: cx.execute('create table test(id integer)') diff --git a/Lib/sqlite3/test/hooks.py b/Lib/sqlite3/test/hooks.py index 6c1aaa2d601..2e620ecdf86 100644 --- a/Lib/sqlite3/test/hooks.py +++ b/Lib/sqlite3/test/hooks.py @@ -260,14 +260,6 @@ class TraceCallbackTests(unittest.TestCase): cur.execute(queries[0]) con2.execute("create table bar(x)") cur.execute(queries[1]) - - # Extract from SQLite 3.7.15 changelog: - # Avoid invoking the sqlite3_trace() callback multiple times when a - # statement is automatically reprepared due to SQLITE_SCHEMA errors. - # - # See bpo-40810 - if sqlite.sqlite_version_info < (3, 7, 15): - queries.append(queries[-1]) self.assertEqual(traced_statements, queries) diff --git a/Misc/NEWS.d/next/Library/2021-01-05-00-52-30.bpo-40810.JxQqPe.rst b/Misc/NEWS.d/next/Library/2021-01-05-00-52-30.bpo-40810.JxQqPe.rst new file mode 100644 index 00000000000..61d8780bb85 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-01-05-00-52-30.bpo-40810.JxQqPe.rst @@ -0,0 +1 @@ +Require SQLite 3.7.15 or newer. Patch by Erlend E. Aasland. diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 1e23daca445..dbe5dd1ec13 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -233,7 +233,7 @@ void pysqlite_connection_dealloc(pysqlite_Connection* self) /* Clean up if user has not called .close() explicitly. */ if (self->db) { - SQLITE3_CLOSE(self->db); + sqlite3_close_v2(self->db); } Py_XDECREF(self->isolation_level); @@ -338,7 +338,7 @@ pysqlite_connection_close_impl(pysqlite_Connection *self) pysqlite_do_all_statements(self, ACTION_FINALIZE, 1); if (self->db) { - rc = SQLITE3_CLOSE(self->db); + rc = sqlite3_close_v2(self->db); if (rc != SQLITE_OK) { _pysqlite_seterror(self->db, NULL); @@ -1687,33 +1687,7 @@ pysqlite_connection_backup_impl(pysqlite_Connection *self, if (rc == SQLITE_NOMEM) { (void)PyErr_NoMemory(); } else { -#if SQLITE_VERSION_NUMBER > 3007015 PyErr_SetString(pysqlite_OperationalError, sqlite3_errstr(rc)); -#else - switch (rc) { - case SQLITE_ERROR: - /* Description of SQLITE_ERROR in SQLite 3.7.14 and older - releases. */ - PyErr_SetString(pysqlite_OperationalError, - "SQL logic error or missing database"); - break; - case SQLITE_READONLY: - PyErr_SetString(pysqlite_OperationalError, - "attempt to write a readonly database"); - break; - case SQLITE_BUSY: - PyErr_SetString(pysqlite_OperationalError, "database is locked"); - break; - case SQLITE_LOCKED: - PyErr_SetString(pysqlite_OperationalError, - "database table is locked"); - break; - default: - PyErr_Format(pysqlite_OperationalError, - "unrecognized error code: %d", rc); - break; - } -#endif } } diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c index cd2eb576c7b..6bfb1b73f82 100644 --- a/Modules/_sqlite/module.c +++ b/Modules/_sqlite/module.c @@ -29,8 +29,8 @@ #include "microprotocols.h" #include "row.h" -#if SQLITE_VERSION_NUMBER < 3007003 -#error "SQLite 3.7.3 or higher required" +#if SQLITE_VERSION_NUMBER < 3007015 +#error "SQLite 3.7.15 or higher required" #endif #include "clinic/module.c.h" @@ -365,8 +365,8 @@ PyMODINIT_FUNC PyInit__sqlite3(void) { PyObject *module; - if (sqlite3_libversion_number() < 3007003) { - PyErr_SetString(PyExc_ImportError, MODULE_NAME ": SQLite 3.7.3 or higher required"); + if (sqlite3_libversion_number() < 3007015) { + PyErr_SetString(PyExc_ImportError, MODULE_NAME ": SQLite 3.7.15 or higher required"); return NULL; } diff --git a/Modules/_sqlite/util.h b/Modules/_sqlite/util.h index c5a220e9b0a..cff31cda957 100644 --- a/Modules/_sqlite/util.h +++ b/Modules/_sqlite/util.h @@ -39,10 +39,4 @@ int _pysqlite_seterror(sqlite3* db, sqlite3_stmt* st); sqlite_int64 _pysqlite_long_as_int64(PyObject * value); -#if SQLITE_VERSION_NUMBER >= 3007014 -#define SQLITE3_CLOSE sqlite3_close_v2 -#else -#define SQLITE3_CLOSE sqlite3_close -#endif - #endif diff --git a/setup.py b/setup.py index 8598d2aa5db..ddc0bd067d4 100644 --- a/setup.py +++ b/setup.py @@ -1444,8 +1444,7 @@ class PyBuildExt(build_ext): ] if CROSS_COMPILING: sqlite_inc_paths = [] - # We need to find >= sqlite version 3.7.3, for sqlite3_create_function_v2() - MIN_SQLITE_VERSION_NUMBER = (3, 7, 3) + MIN_SQLITE_VERSION_NUMBER = (3, 7, 15) # Issue 40810 MIN_SQLITE_VERSION = ".".join([str(x) for x in MIN_SQLITE_VERSION_NUMBER])