summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErlend E. Aasland <erlend@python.org>2023-08-15 08:09:56 (GMT)
committerGitHub <noreply@github.com>2023-08-15 08:09:56 (GMT)
commit13c36dc9ae5240124932137de4a94d81292c6c5f (patch)
treed0c519b57139c9af90bec3f6df794d37fdaf94b1
parenta482e5bf0022f85424a6308529a9ad51f1bfbb71 (diff)
downloadcpython-13c36dc9ae5240124932137de4a94d81292c6c5f.zip
cpython-13c36dc9ae5240124932137de4a94d81292c6c5f.tar.gz
cpython-13c36dc9ae5240124932137de4a94d81292c6c5f.tar.bz2
gh-93057: Deprecate positional use of optional sqlite3.connect() params (#107948)
-rw-r--r--Doc/library/sqlite3.rst6
-rw-r--r--Doc/whatsnew/3.13.rst5
-rw-r--r--Lib/test/test_sqlite3/test_dbapi.py13
-rw-r--r--Lib/test/test_sqlite3/test_factory.py11
-rw-r--r--Misc/NEWS.d/next/Library/2023-08-14-19-49-02.gh-issue-93057.5nJwO5.rst3
-rw-r--r--Modules/_sqlite/clinic/_sqlite3.connect.c.h10
-rw-r--r--Modules/_sqlite/clinic/connection.c.h35
-rw-r--r--Modules/_sqlite/connection.c3
-rw-r--r--Modules/_sqlite/module.c11
9 files changed, 92 insertions, 5 deletions
diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst
index 5034405..5f1676e 100644
--- a/Doc/library/sqlite3.rst
+++ b/Doc/library/sqlite3.rst
@@ -355,6 +355,12 @@ Module functions
.. versionadded:: 3.12
The *autocommit* parameter.
+ .. versionchanged:: 3.13
+ Positional use of the parameters *timeout*, *detect_types*,
+ *isolation_level*, *check_same_thread*, *factory*, *cached_statements*,
+ and *uri* is deprecated.
+ They will become keyword-only parameters in Python 3.15.
+
.. function:: complete_statement(statement)
Return ``True`` if the string *statement* appears to contain
diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst
index 63cdee6..a65a98b 100644
--- a/Doc/whatsnew/3.13.rst
+++ b/Doc/whatsnew/3.13.rst
@@ -219,6 +219,11 @@ Deprecated
They will be removed in Python 3.15.
(Contributed by Victor Stinner in :gh:`105096`.)
+* Passing more than one positional argument to :func:`sqlite3.connect` and the
+ :class:`sqlite3.Connection` constructor is deprecated. The remaining
+ parameters will become keyword-only in Python 3.15.
+ (Contributed by Erlend E. Aasland in :gh:`107948`.)
+
Pending Removal in Python 3.14
------------------------------
diff --git a/Lib/test/test_sqlite3/test_dbapi.py b/Lib/test/test_sqlite3/test_dbapi.py
index 3f9bd02..c9a9e13 100644
--- a/Lib/test/test_sqlite3/test_dbapi.py
+++ b/Lib/test/test_sqlite3/test_dbapi.py
@@ -582,6 +582,19 @@ class ConnectionTests(unittest.TestCase):
with self.assertRaisesRegex(sqlite.IntegrityError, "constraint"):
cx.execute("insert into u values(0)")
+ def test_connect_positional_arguments(self):
+ regex = (
+ r"Passing more than 1 positional argument to sqlite3.connect\(\)"
+ " is deprecated. Parameters 'timeout', 'detect_types', "
+ "'isolation_level', 'check_same_thread', 'factory', "
+ "'cached_statements' and 'uri' will become keyword-only "
+ "parameters in Python 3.15."
+ )
+ with self.assertWarnsRegex(DeprecationWarning, regex) as cm:
+ sqlite.connect(":memory:", 1.0)
+ self.assertEqual(cm.filename, __file__)
+
+
class UninitialisedConnectionTests(unittest.TestCase):
def setUp(self):
diff --git a/Lib/test/test_sqlite3/test_factory.py b/Lib/test/test_sqlite3/test_factory.py
index 7c36135..d635894 100644
--- a/Lib/test/test_sqlite3/test_factory.py
+++ b/Lib/test/test_sqlite3/test_factory.py
@@ -66,7 +66,16 @@ class ConnectionFactoryTests(unittest.TestCase):
def __init__(self, *args, **kwargs):
super(Factory, self).__init__(*args, **kwargs)
- con = sqlite.connect(":memory:", 5.0, 0, None, True, Factory)
+ regex = (
+ r"Passing more than 1 positional argument to _sqlite3.Connection\(\) "
+ r"is deprecated. Parameters 'timeout', 'detect_types', "
+ r"'isolation_level', 'check_same_thread', 'factory', "
+ r"'cached_statements' and 'uri' will become keyword-only "
+ r"parameters in Python 3.15."
+ )
+ with self.assertWarnsRegex(DeprecationWarning, regex) as cm:
+ con = sqlite.connect(":memory:", 5.0, 0, None, True, Factory)
+ self.assertEqual(cm.filename, __file__)
self.assertIsNone(con.isolation_level)
self.assertIsInstance(con, Factory)
diff --git a/Misc/NEWS.d/next/Library/2023-08-14-19-49-02.gh-issue-93057.5nJwO5.rst b/Misc/NEWS.d/next/Library/2023-08-14-19-49-02.gh-issue-93057.5nJwO5.rst
new file mode 100644
index 0000000..6a4feaa
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-08-14-19-49-02.gh-issue-93057.5nJwO5.rst
@@ -0,0 +1,3 @@
+Passing more than one positional argument to :func:`sqlite3.connect` and the
+:class:`sqlite3.Connection` constructor is deprecated. The remaining parameters
+will become keyword-only in Python 3.15. Patch by Erlend E. Aasland.
diff --git a/Modules/_sqlite/clinic/_sqlite3.connect.c.h b/Modules/_sqlite/clinic/_sqlite3.connect.c.h
index 0c4ebdf..998c8de 100644
--- a/Modules/_sqlite/clinic/_sqlite3.connect.c.h
+++ b/Modules/_sqlite/clinic/_sqlite3.connect.c.h
@@ -18,8 +18,14 @@ PyDoc_STRVAR(pysqlite_connect__doc__,
"Open a connection to the SQLite database file \'database\'.\n"
"\n"
"You can use \":memory:\" to open a database connection to a database that\n"
-"resides in RAM instead of on disk.");
+"resides in RAM instead of on disk.\n"
+"\n"
+"Note: Passing more than 1 positional argument to _sqlite3.connect() is\n"
+"deprecated. Parameters \'timeout\', \'detect_types\', \'isolation_level\',\n"
+"\'check_same_thread\', \'factory\', \'cached_statements\' and \'uri\' will\n"
+"become keyword-only parameters in Python 3.15.\n"
+"");
#define PYSQLITE_CONNECT_METHODDEF \
{"connect", _PyCFunction_CAST(pysqlite_connect), METH_FASTCALL|METH_KEYWORDS, pysqlite_connect__doc__},
-/*[clinic end generated code: output=6a8458c9edf8fb7f input=a9049054013a1b77]*/
+/*[clinic end generated code: output=8d49736db880f09a input=a9049054013a1b77]*/
diff --git a/Modules/_sqlite/clinic/connection.c.h b/Modules/_sqlite/clinic/connection.c.h
index e869d7d..af98d61 100644
--- a/Modules/_sqlite/clinic/connection.c.h
+++ b/Modules/_sqlite/clinic/connection.c.h
@@ -59,6 +59,39 @@ pysqlite_connection_init(PyObject *self, PyObject *args, PyObject *kwargs)
int uri = 0;
enum autocommit_mode autocommit = LEGACY_TRANSACTION_CONTROL;
+ // Emit compiler warnings when we get to Python 3.15.
+ #if PY_VERSION_HEX >= 0x030f00C0
+ # error \
+ "In connection.c, update parameter(s) 'timeout', 'detect_types', " \
+ "'isolation_level', 'check_same_thread', 'factory', " \
+ "'cached_statements' and 'uri' in the clinic input of " \
+ "'_sqlite3.Connection.__init__' to be keyword-only."
+ #elif PY_VERSION_HEX >= 0x030f00A0
+ # ifdef _MSC_VER
+ # pragma message ( \
+ "In connection.c, update parameter(s) 'timeout', 'detect_types', " \
+ "'isolation_level', 'check_same_thread', 'factory', " \
+ "'cached_statements' and 'uri' in the clinic input of " \
+ "'_sqlite3.Connection.__init__' to be keyword-only.")
+ # else
+ # warning \
+ "In connection.c, update parameter(s) 'timeout', 'detect_types', " \
+ "'isolation_level', 'check_same_thread', 'factory', " \
+ "'cached_statements' and 'uri' in the clinic input of " \
+ "'_sqlite3.Connection.__init__' to be keyword-only."
+ # endif
+ #endif
+ if (nargs > 1 && nargs <= 8) {
+ if (PyErr_WarnEx(PyExc_DeprecationWarning,
+ "Passing more than 1 positional argument to _sqlite3.Connection()"
+ " is deprecated. Parameters 'timeout', 'detect_types', "
+ "'isolation_level', 'check_same_thread', 'factory', "
+ "'cached_statements' and 'uri' will become keyword-only "
+ "parameters in Python 3.15.", 1))
+ {
+ goto exit;
+ }
+ }
fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 8, 0, argsbuf);
if (!fastargs) {
goto exit;
@@ -1659,4 +1692,4 @@ exit:
#ifndef DESERIALIZE_METHODDEF
#define DESERIALIZE_METHODDEF
#endif /* !defined(DESERIALIZE_METHODDEF) */
-/*[clinic end generated code: output=d3c6cb9326736ea5 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=5a05e5294ad9d2ce input=a9049054013a1b77]*/
diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c
index 3d2fcd3..0819acd 100644
--- a/Modules/_sqlite/connection.c
+++ b/Modules/_sqlite/connection.c
@@ -216,6 +216,7 @@ class sqlite3_int64_converter(CConverter):
_sqlite3.Connection.__init__ as pysqlite_connection_init
database: object
+ * [from 3.15]
timeout: double = 5.0
detect_types: int = 0
isolation_level: IsolationLevel = ""
@@ -234,7 +235,7 @@ pysqlite_connection_init_impl(pysqlite_Connection *self, PyObject *database,
int check_same_thread, PyObject *factory,
int cache_size, int uri,
enum autocommit_mode autocommit)
-/*[clinic end generated code: output=cba057313ea7712f input=9b0ab6c12f674fa3]*/
+/*[clinic end generated code: output=cba057313ea7712f input=219c3dbecbae7d99]*/
{
if (PySys_Audit("sqlite3.connect", "O", database) < 0) {
return -1;
diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c
index 0c503df..dd45ffc 100644
--- a/Modules/_sqlite/module.c
+++ b/Modules/_sqlite/module.c
@@ -64,6 +64,17 @@ pysqlite_connect(PyObject *module, PyObject *const *args, Py_ssize_t nargsf,
static const int FACTORY_POS = 5;
Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
+ if (nargs > 1 && nargs <= 8) {
+ if (PyErr_WarnEx(PyExc_DeprecationWarning,
+ "Passing more than 1 positional argument to sqlite3.connect()"
+ " is deprecated. Parameters 'timeout', 'detect_types', "
+ "'isolation_level', 'check_same_thread', 'factory', "
+ "'cached_statements' and 'uri' will become keyword-only "
+ "parameters in Python 3.15.", 1))
+ {
+ return NULL;
+ }
+ }
if (nargs > FACTORY_POS) {
factory = args[FACTORY_POS];
}