mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
gh-101693: In sqlite3, deprecate using named placeholders with parameters supplied as a sequence (#101698)
This commit is contained in:
parent
d777790bab
commit
8a2b7ee64d
5 changed files with 59 additions and 1 deletions
|
@ -1442,6 +1442,14 @@ Cursor objects
|
|||
and there is no open transaction,
|
||||
a transaction is implicitly opened before executing *sql*.
|
||||
|
||||
.. deprecated-removed:: 3.12 3.14
|
||||
|
||||
:exc:`DeprecationWarning` is emitted if
|
||||
:ref:`named placeholders <sqlite3-placeholders>` are used
|
||||
and *parameters* is a sequence instead of a :class:`dict`.
|
||||
Starting with Python 3.14, :exc:`ProgrammingError` will
|
||||
be raised instead.
|
||||
|
||||
Use :meth:`executescript` to execute multiple SQL statements.
|
||||
|
||||
.. method:: executemany(sql, parameters, /)
|
||||
|
@ -1476,6 +1484,15 @@ Cursor objects
|
|||
# cur is an sqlite3.Cursor object
|
||||
cur.executemany("INSERT INTO data VALUES(?)", rows)
|
||||
|
||||
.. deprecated-removed:: 3.12 3.14
|
||||
|
||||
:exc:`DeprecationWarning` is emitted if
|
||||
:ref:`named placeholders <sqlite3-placeholders>` are used
|
||||
and the items in *parameters* are sequences
|
||||
instead of :class:`dict`\s.
|
||||
Starting with Python 3.14, :exc:`ProgrammingError` will
|
||||
be raised instead.
|
||||
|
||||
.. method:: executescript(sql_script, /)
|
||||
|
||||
Execute the SQL statements in *sql_script*.
|
||||
|
@ -1971,7 +1988,7 @@ question marks (qmark style) or named placeholders (named style).
|
|||
For the qmark style, *parameters* must be a
|
||||
:term:`sequence` whose length must match the number of placeholders,
|
||||
or a :exc:`ProgrammingError` is raised.
|
||||
For the named style, *parameters* should be
|
||||
For the named style, *parameters* must be
|
||||
an instance of a :class:`dict` (or a subclass),
|
||||
which must contain keys for all named parameters;
|
||||
any extra items are ignored.
|
||||
|
|
|
@ -415,6 +415,13 @@ Deprecated
|
|||
and tailor them to your needs.
|
||||
(Contributed by Erlend E. Aasland in :gh:`90016`.)
|
||||
|
||||
* In :meth:`~sqlite3.Cursor.execute`, :exc:`DeprecationWarning` is now emitted
|
||||
when :ref:`named placeholders <sqlite3-placeholders>` are used together with
|
||||
parameters supplied as a :term:`sequence` instead of as a :class:`dict`.
|
||||
Starting from Python 3.14, using named placeholders with parameters supplied
|
||||
as a sequence will raise a :exc:`~sqlite3.ProgrammingError`.
|
||||
(Contributed by Erlend E. Aasland in :gh:`101698`.)
|
||||
|
||||
* The 3-arg signatures (type, value, traceback) of :meth:`~coroutine.throw`,
|
||||
:meth:`~generator.throw` and :meth:`~agen.athrow` are deprecated and
|
||||
may be removed in a future version of Python. Use the single-arg versions
|
||||
|
|
|
@ -861,6 +861,21 @@ class CursorTests(unittest.TestCase):
|
|||
with self.assertRaises(ZeroDivisionError):
|
||||
self.cu.execute("select name from test where name=?", L())
|
||||
|
||||
def test_execute_named_param_and_sequence(self):
|
||||
dataset = (
|
||||
("select :a", (1,)),
|
||||
("select :a, ?, ?", (1, 2, 3)),
|
||||
("select ?, :b, ?", (1, 2, 3)),
|
||||
("select ?, ?, :c", (1, 2, 3)),
|
||||
("select :a, :b, ?", (1, 2, 3)),
|
||||
)
|
||||
msg = "Binding.*is a named parameter"
|
||||
for query, params in dataset:
|
||||
with self.subTest(query=query, params=params):
|
||||
with self.assertWarnsRegex(DeprecationWarning, msg) as cm:
|
||||
self.cu.execute(query, params)
|
||||
self.assertEqual(cm.filename, __file__)
|
||||
|
||||
def test_execute_too_many_params(self):
|
||||
category = sqlite.SQLITE_LIMIT_VARIABLE_NUMBER
|
||||
msg = "too many SQL variables"
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
In :meth:`sqlite3.Cursor.execute`, :exc:`DeprecationWarning` is now emitted
|
||||
when :ref:`named placeholders <sqlite3-placeholders>` are used together with
|
||||
parameters supplied as a :term:`sequence` instead of as a :class:`dict`.
|
||||
Starting from Python 3.14, using named placeholders with parameters supplied
|
||||
as a sequence will raise a :exc:`~sqlite3.ProgrammingError`.
|
||||
Patch by Erlend E. Aasland.
|
|
@ -662,6 +662,19 @@ bind_parameters(pysqlite_state *state, pysqlite_Statement *self,
|
|||
return;
|
||||
}
|
||||
for (i = 0; i < num_params; i++) {
|
||||
const char *name = sqlite3_bind_parameter_name(self->st, i+1);
|
||||
if (name != NULL) {
|
||||
int ret = PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
|
||||
"Binding %d ('%s') is a named parameter, but you "
|
||||
"supplied a sequence which requires nameless (qmark) "
|
||||
"placeholders. Starting with Python 3.14 an "
|
||||
"sqlite3.ProgrammingError will be raised.",
|
||||
i+1, name);
|
||||
if (ret < 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (PyTuple_CheckExact(parameters)) {
|
||||
PyObject *item = PyTuple_GET_ITEM(parameters, i);
|
||||
current_param = Py_NewRef(item);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue