gh-117995: Don't raise DeprecationWarnings for indexed nameless params (#118001)

Filter out '?NNN' placeholders when looking for named params.

Co-authored-by: AN Long <aisk@users.noreply.github.com>
This commit is contained in:
Erlend E. Aasland 2024-04-22 08:43:20 +02:00 committed by GitHub
parent 8b541c017e
commit 550483b7e6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 17 additions and 1 deletions

View File

@ -28,6 +28,7 @@ import sys
import threading import threading
import unittest import unittest
import urllib.parse import urllib.parse
import warnings
from test.support import ( from test.support import (
SHORT_TIMEOUT, check_disallow_instantiation, requires_subprocess, SHORT_TIMEOUT, check_disallow_instantiation, requires_subprocess,
@ -887,6 +888,19 @@ class CursorTests(unittest.TestCase):
self.cu.execute(query, params) self.cu.execute(query, params)
self.assertEqual(cm.filename, __file__) self.assertEqual(cm.filename, __file__)
def test_execute_indexed_nameless_params(self):
# See gh-117995: "'?1' is considered a named placeholder"
for query, params, expected in (
("select ?1, ?2", (1, 2), (1, 2)),
("select ?2, ?1", (1, 2), (2, 1)),
):
with self.subTest(query=query, params=params):
with warnings.catch_warnings():
warnings.simplefilter("error", DeprecationWarning)
cu = self.cu.execute(query, params)
actual, = cu.fetchall()
self.assertEqual(actual, expected)
def test_execute_too_many_params(self): def test_execute_too_many_params(self):
category = sqlite.SQLITE_LIMIT_VARIABLE_NUMBER category = sqlite.SQLITE_LIMIT_VARIABLE_NUMBER
msg = "too many SQL variables" msg = "too many SQL variables"

View File

@ -0,0 +1,2 @@
Don't raise :exc:`DeprecationWarning` when a :term:`sequence` of parameters
is used to bind indexed, nameless placeholders. See also :gh:`100668`.

View File

@ -669,7 +669,7 @@ bind_parameters(pysqlite_state *state, pysqlite_Statement *self,
} }
for (i = 0; i < num_params; i++) { for (i = 0; i < num_params; i++) {
const char *name = sqlite3_bind_parameter_name(self->st, i+1); const char *name = sqlite3_bind_parameter_name(self->st, i+1);
if (name != NULL) { if (name != NULL && name[0] != '?') {
int ret = PyErr_WarnFormat(PyExc_DeprecationWarning, 1, int ret = PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
"Binding %d ('%s') is a named parameter, but you " "Binding %d ('%s') is a named parameter, but you "
"supplied a sequence which requires nameless (qmark) " "supplied a sequence which requires nameless (qmark) "