From 40996ef579c1e46fc9720118fb8c91d19bb3fd99 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 14 Aug 2023 19:50:28 +0200 Subject: [PATCH 1/7] gh-93057: Deprecate positional use of optional sqlite3.connect() params --- Doc/library/sqlite3.rst | 6 ++++ Doc/whatsnew/3.13.rst | 15 ++++++++ ...3-08-14-19-49-02.gh-issue-93057.5nJwO5.rst | 5 +++ Modules/_sqlite/clinic/_sqlite3.connect.c.h | 10 ++++-- Modules/_sqlite/clinic/connection.c.h | 35 ++++++++++++++++++- Modules/_sqlite/connection.c | 5 +-- 6 files changed, 71 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2023-08-14-19-49-02.gh-issue-93057.5nJwO5.rst diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 50344058c26041..5f1676e5ae2f56 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 63cdee6cf1a4f3..65181140403b6c 100644 --- a/Doc/whatsnew/3.13.rst +++ b/Doc/whatsnew/3.13.rst @@ -144,6 +144,15 @@ pathlib :meth:`~pathlib.Path.is_dir`. (Contributed by Barney Gale in :gh:`77609` and :gh:`105793`.) +sqlite3 +------- + +* Passing more than one positional argument to :func:`sqlite3.connect` is + deprecated. 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. + (Contributed by Erlend E. Aasland :gh:`93057`.) + traceback --------- @@ -219,6 +228,12 @@ 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` is + deprecated. 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. + (Contributed by Erlend E. Aasland :gh:`93057`.) + Pending Removal in Python 3.14 ------------------------------ 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 00000000000000..8715e07362f236 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-08-14-19-49-02.gh-issue-93057.5nJwO5.rst @@ -0,0 +1,5 @@ +Passing more than one positional argument to :func:`sqlite3.connect` is +deprecated. 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. Patch +by Erlend E. Aasland. diff --git a/Modules/_sqlite/clinic/_sqlite3.connect.c.h b/Modules/_sqlite/clinic/_sqlite3.connect.c.h index 0c4ebdf0590c9e..998c8de1e09f16 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 e869d7d9e9384c..af98d61ea7cccc 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 @@ getconfig(pysqlite_Connection *self, PyObject *arg) #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 3d2fcd3ae0788e..cdf19a40e0dd47 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -213,9 +213,10 @@ class sqlite3_int64_converter(CConverter): /*[python end generated code: output=da39a3ee5e6b4b0d input=dff8760fb1eba6a1]*/ /*[clinic input] -_sqlite3.Connection.__init__ as pysqlite_connection_init +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; From b84ee0e3603d1ed56dc7f8fd2b418b184579a6ca Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 14 Aug 2023 21:45:18 +0200 Subject: [PATCH 2/7] Fix test and news entries --- Doc/whatsnew/3.13.rst | 9 ++------- Lib/test/test_sqlite3/test_factory.py | 10 +++++++++- .../2023-08-14-19-49-02.gh-issue-93057.5nJwO5.rst | 6 ++---- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst index 65181140403b6c..bfed1abc5228e2 100644 --- a/Doc/whatsnew/3.13.rst +++ b/Doc/whatsnew/3.13.rst @@ -148,9 +148,7 @@ sqlite3 ------- * Passing more than one positional argument to :func:`sqlite3.connect` is - deprecated. 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. + deprecated. The remaining parameters will become keyword-only in Python 3.15. (Contributed by Erlend E. Aasland :gh:`93057`.) traceback @@ -229,10 +227,7 @@ Deprecated (Contributed by Victor Stinner in :gh:`105096`.) * Passing more than one positional argument to :func:`sqlite3.connect` is - deprecated. 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. - (Contributed by Erlend E. Aasland :gh:`93057`.) + deprecated. The remaining parameters will become keyword-only in Python 3.15. Pending Removal in Python 3.14 ------------------------------ diff --git a/Lib/test/test_sqlite3/test_factory.py b/Lib/test/test_sqlite3/test_factory.py index 7c36135ecadccd..a11ced86f475b3 100644 --- a/Lib/test/test_sqlite3/test_factory.py +++ b/Lib/test/test_sqlite3/test_factory.py @@ -66,7 +66,15 @@ class Factory(sqlite.Connection): 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): + con = sqlite.connect(":memory:", 5.0, 0, None, True, Factory) 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 index 8715e07362f236..38d25aa8fb54aa 100644 --- 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 @@ -1,5 +1,3 @@ Passing more than one positional argument to :func:`sqlite3.connect` is -deprecated. 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. Patch -by Erlend E. Aasland. +deprecated. The remaining parameters will become keyword-only in Python 3.15. +Patch by Erlend E. Aasland. From 6ab04fd6fdfe96b868c4b9051a3887a4f0d4c0eb Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 14 Aug 2023 22:43:41 +0200 Subject: [PATCH 3/7] regen clinic --- Modules/_sqlite/connection.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index cdf19a40e0dd47..0819acd0940964 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -213,7 +213,7 @@ class sqlite3_int64_converter(CConverter): /*[python end generated code: output=da39a3ee5e6b4b0d input=dff8760fb1eba6a1]*/ /*[clinic input] -sqlite3.Connection.__init__ as pysqlite_connection_init +_sqlite3.Connection.__init__ as pysqlite_connection_init database: object * [from 3.15] From 01c40673aaea12be4a714451053f3dc9aa74b6a2 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Mon, 14 Aug 2023 23:07:01 +0200 Subject: [PATCH 4/7] Address review: don't repeat the what's new entry --- Doc/whatsnew/3.13.rst | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst index bfed1abc5228e2..c39d3dc0f8deb5 100644 --- a/Doc/whatsnew/3.13.rst +++ b/Doc/whatsnew/3.13.rst @@ -144,13 +144,6 @@ pathlib :meth:`~pathlib.Path.is_dir`. (Contributed by Barney Gale in :gh:`77609` and :gh:`105793`.) -sqlite3 -------- - -* Passing more than one positional argument to :func:`sqlite3.connect` is - deprecated. The remaining parameters will become keyword-only in Python 3.15. - (Contributed by Erlend E. Aasland :gh:`93057`.) - traceback --------- From de7e87cc0733b90c2693becac059dd72b58e925a Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 15 Aug 2023 08:57:31 +0200 Subject: [PATCH 5/7] Manually insert deprecation warning for sqlite3.connect --- Modules/_sqlite/module.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c index 0c503dfbebbd6c..dd45ffc1988f7e 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]; } From 4018bd91aa5400b0600171b14c4a8f78ee8f3c87 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 15 Aug 2023 09:23:10 +0200 Subject: [PATCH 6/7] Also test module level connect() --- Lib/test/test_sqlite3/test_dbapi.py | 13 +++++++++++++ Lib/test/test_sqlite3/test_factory.py | 3 ++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_sqlite3/test_dbapi.py b/Lib/test/test_sqlite3/test_dbapi.py index 3f9bd0248a8b96..c9a9e1353938c6 100644 --- a/Lib/test/test_sqlite3/test_dbapi.py +++ b/Lib/test/test_sqlite3/test_dbapi.py @@ -582,6 +582,19 @@ def test_connection_config(self): 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 a11ced86f475b3..d63589483e1042 100644 --- a/Lib/test/test_sqlite3/test_factory.py +++ b/Lib/test/test_sqlite3/test_factory.py @@ -73,8 +73,9 @@ def __init__(self, *args, **kwargs): r"'cached_statements' and 'uri' will become keyword-only " r"parameters in Python 3.15." ) - with self.assertWarnsRegex(DeprecationWarning, regex): + 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) From 1f487833c75c4aa00bfcd60b185ae962a3bb5c3a Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Tue, 15 Aug 2023 09:33:42 +0200 Subject: [PATCH 7/7] Also mention the Connection constructor in What's New/NEWS --- Doc/whatsnew/3.13.rst | 6 ++++-- .../Library/2023-08-14-19-49-02.gh-issue-93057.5nJwO5.rst | 6 +++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst index c39d3dc0f8deb5..a65a98bae13579 100644 --- a/Doc/whatsnew/3.13.rst +++ b/Doc/whatsnew/3.13.rst @@ -219,8 +219,10 @@ 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` is - deprecated. The remaining parameters will become keyword-only in Python 3.15. +* 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/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 index 38d25aa8fb54aa..6a4feaac25bc11 100644 --- 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 @@ -1,3 +1,3 @@ -Passing more than one positional argument to :func:`sqlite3.connect` is -deprecated. The remaining parameters will become keyword-only in Python 3.15. -Patch by Erlend E. Aasland. +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.