From 68010fefe2af5222174f0386762b7825f6ac48ef Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 13 Jan 2021 12:35:09 +0100 Subject: [PATCH 1/8] bpo-40956: fix Cursor.fetchmany() default value --- Modules/_sqlite/clinic/cursor.c.h | 4 ++-- Modules/_sqlite/cursor.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Modules/_sqlite/clinic/cursor.c.h b/Modules/_sqlite/clinic/cursor.c.h index d5cf0a5eaadae1..2d495515d22ef0 100644 --- a/Modules/_sqlite/clinic/cursor.c.h +++ b/Modules/_sqlite/clinic/cursor.c.h @@ -138,7 +138,7 @@ pysqlite_cursor_fetchone(pysqlite_Cursor *self, PyObject *Py_UNUSED(ignored)) } PyDoc_STRVAR(pysqlite_cursor_fetchmany__doc__, -"fetchmany($self, /, size=cursor.arraysize)\n" +"fetchmany($self, /, size=)\n" "--\n" "\n" "Fetches several rows from the resultset."); @@ -256,4 +256,4 @@ pysqlite_cursor_close(pysqlite_Cursor *self, PyObject *Py_UNUSED(ignored)) { return pysqlite_cursor_close_impl(self); } -/*[clinic end generated code: output=11db0de4fb1951a9 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8b5ffd9029d33cd8 input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 296d569148f8ae..2b693a17e9b9ca 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -822,14 +822,14 @@ pysqlite_cursor_fetchone_impl(pysqlite_Cursor *self) /*[clinic input] _sqlite3.Cursor.fetchmany as pysqlite_cursor_fetchmany - size as maxrows: int(c_default='self->arraysize') = cursor.arraysize + size as maxrows: int(c_default='self->arraysize', py_default='') = 1 Fetches several rows from the resultset. [clinic start generated code]*/ static PyObject * pysqlite_cursor_fetchmany_impl(pysqlite_Cursor *self, int maxrows) -/*[clinic end generated code: output=a8ef31fea64d0906 input=d80ff999a7701ffb]*/ +/*[clinic end generated code: output=a8ef31fea64d0906 input=e436f4f150e78b9b]*/ { PyObject* row; PyObject* list; From 3d1616af8feb7d8448e10caa5161d9add51a4096 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 13 Jan 2021 22:24:40 +0100 Subject: [PATCH 2/8] Address review --- Modules/_sqlite/clinic/cursor.c.h | 18 +++++++++--------- Modules/_sqlite/cursor.c | 14 +++++++++++--- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/Modules/_sqlite/clinic/cursor.c.h b/Modules/_sqlite/clinic/cursor.c.h index 2d495515d22ef0..26c64d9f535476 100644 --- a/Modules/_sqlite/clinic/cursor.c.h +++ b/Modules/_sqlite/clinic/cursor.c.h @@ -141,13 +141,16 @@ PyDoc_STRVAR(pysqlite_cursor_fetchmany__doc__, "fetchmany($self, /, size=)\n" "--\n" "\n" -"Fetches several rows from the resultset."); +"Fetches several rows from the resultset.\n" +"\n" +" size\n" +" The number of rows to fetch. Defaults to the cursor\'s arraysize."); #define PYSQLITE_CURSOR_FETCHMANY_METHODDEF \ {"fetchmany", (PyCFunction)(void(*)(void))pysqlite_cursor_fetchmany, METH_FASTCALL|METH_KEYWORDS, pysqlite_cursor_fetchmany__doc__}, static PyObject * -pysqlite_cursor_fetchmany_impl(pysqlite_Cursor *self, int maxrows); +pysqlite_cursor_fetchmany_impl(pysqlite_Cursor *self, PyObject *maxrows_obj); static PyObject * pysqlite_cursor_fetchmany(pysqlite_Cursor *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) @@ -157,7 +160,7 @@ pysqlite_cursor_fetchmany(pysqlite_Cursor *self, PyObject *const *args, Py_ssize static _PyArg_Parser _parser = {NULL, _keywords, "fetchmany", 0}; PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - int maxrows = self->arraysize; + PyObject *maxrows_obj = NULL; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); if (!args) { @@ -166,12 +169,9 @@ pysqlite_cursor_fetchmany(pysqlite_Cursor *self, PyObject *const *args, Py_ssize if (!noptargs) { goto skip_optional_pos; } - maxrows = _PyLong_AsInt(args[0]); - if (maxrows == -1 && PyErr_Occurred()) { - goto exit; - } + maxrows_obj = args[0]; skip_optional_pos: - return_value = pysqlite_cursor_fetchmany_impl(self, maxrows); + return_value = pysqlite_cursor_fetchmany_impl(self, maxrows_obj); exit: return return_value; @@ -256,4 +256,4 @@ pysqlite_cursor_close(pysqlite_Cursor *self, PyObject *Py_UNUSED(ignored)) { return pysqlite_cursor_close_impl(self); } -/*[clinic end generated code: output=8b5ffd9029d33cd8 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=53cab2e724cd2ba5 input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 2b693a17e9b9ca..042672f2ccc90f 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -822,18 +822,26 @@ pysqlite_cursor_fetchone_impl(pysqlite_Cursor *self) /*[clinic input] _sqlite3.Cursor.fetchmany as pysqlite_cursor_fetchmany - size as maxrows: int(c_default='self->arraysize', py_default='') = 1 + size as maxrows_obj: object = NULL + The number of rows to fetch. Defaults to the cursor's arraysize. Fetches several rows from the resultset. [clinic start generated code]*/ static PyObject * -pysqlite_cursor_fetchmany_impl(pysqlite_Cursor *self, int maxrows) -/*[clinic end generated code: output=a8ef31fea64d0906 input=e436f4f150e78b9b]*/ +pysqlite_cursor_fetchmany_impl(pysqlite_Cursor *self, PyObject *maxrows_obj) +/*[clinic end generated code: output=91a37190dafbc2de input=d8c699ff7e0db461]*/ { PyObject* row; PyObject* list; int counter = 0; + int maxrows; + + if (maxrows_obj == NULL) { + maxrows = self->arraysize; + } else if (PyLong_Check(maxrows_obj) < 0) { + maxrows = PyLong_AsLong(maxrows_obj); + } list = PyList_New(0); if (!list) { From 37b8354ddd0b9f76177bd401089ac05975cbc751 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 13 Jan 2021 23:02:50 +0100 Subject: [PATCH 3/8] Revert "Address review" This reverts commit 3d1616af8feb7d8448e10caa5161d9add51a4096. --- Modules/_sqlite/clinic/cursor.c.h | 18 +++++++++--------- Modules/_sqlite/cursor.c | 14 +++----------- 2 files changed, 12 insertions(+), 20 deletions(-) diff --git a/Modules/_sqlite/clinic/cursor.c.h b/Modules/_sqlite/clinic/cursor.c.h index 26c64d9f535476..2d495515d22ef0 100644 --- a/Modules/_sqlite/clinic/cursor.c.h +++ b/Modules/_sqlite/clinic/cursor.c.h @@ -141,16 +141,13 @@ PyDoc_STRVAR(pysqlite_cursor_fetchmany__doc__, "fetchmany($self, /, size=)\n" "--\n" "\n" -"Fetches several rows from the resultset.\n" -"\n" -" size\n" -" The number of rows to fetch. Defaults to the cursor\'s arraysize."); +"Fetches several rows from the resultset."); #define PYSQLITE_CURSOR_FETCHMANY_METHODDEF \ {"fetchmany", (PyCFunction)(void(*)(void))pysqlite_cursor_fetchmany, METH_FASTCALL|METH_KEYWORDS, pysqlite_cursor_fetchmany__doc__}, static PyObject * -pysqlite_cursor_fetchmany_impl(pysqlite_Cursor *self, PyObject *maxrows_obj); +pysqlite_cursor_fetchmany_impl(pysqlite_Cursor *self, int maxrows); static PyObject * pysqlite_cursor_fetchmany(pysqlite_Cursor *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) @@ -160,7 +157,7 @@ pysqlite_cursor_fetchmany(pysqlite_Cursor *self, PyObject *const *args, Py_ssize static _PyArg_Parser _parser = {NULL, _keywords, "fetchmany", 0}; PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - PyObject *maxrows_obj = NULL; + int maxrows = self->arraysize; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); if (!args) { @@ -169,9 +166,12 @@ pysqlite_cursor_fetchmany(pysqlite_Cursor *self, PyObject *const *args, Py_ssize if (!noptargs) { goto skip_optional_pos; } - maxrows_obj = args[0]; + maxrows = _PyLong_AsInt(args[0]); + if (maxrows == -1 && PyErr_Occurred()) { + goto exit; + } skip_optional_pos: - return_value = pysqlite_cursor_fetchmany_impl(self, maxrows_obj); + return_value = pysqlite_cursor_fetchmany_impl(self, maxrows); exit: return return_value; @@ -256,4 +256,4 @@ pysqlite_cursor_close(pysqlite_Cursor *self, PyObject *Py_UNUSED(ignored)) { return pysqlite_cursor_close_impl(self); } -/*[clinic end generated code: output=53cab2e724cd2ba5 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8b5ffd9029d33cd8 input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 042672f2ccc90f..2b693a17e9b9ca 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -822,26 +822,18 @@ pysqlite_cursor_fetchone_impl(pysqlite_Cursor *self) /*[clinic input] _sqlite3.Cursor.fetchmany as pysqlite_cursor_fetchmany - size as maxrows_obj: object = NULL - The number of rows to fetch. Defaults to the cursor's arraysize. + size as maxrows: int(c_default='self->arraysize', py_default='') = 1 Fetches several rows from the resultset. [clinic start generated code]*/ static PyObject * -pysqlite_cursor_fetchmany_impl(pysqlite_Cursor *self, PyObject *maxrows_obj) -/*[clinic end generated code: output=91a37190dafbc2de input=d8c699ff7e0db461]*/ +pysqlite_cursor_fetchmany_impl(pysqlite_Cursor *self, int maxrows) +/*[clinic end generated code: output=a8ef31fea64d0906 input=e436f4f150e78b9b]*/ { PyObject* row; PyObject* list; int counter = 0; - int maxrows; - - if (maxrows_obj == NULL) { - maxrows = self->arraysize; - } else if (PyLong_Check(maxrows_obj) < 0) { - maxrows = PyLong_AsLong(maxrows_obj); - } list = PyList_New(0); if (!list) { From 36567076ec9aa4da59829e71555e229a4e1945e5 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 13 Jan 2021 23:09:44 +0100 Subject: [PATCH 4/8] Add argument docstring, explaining the default value --- Modules/_sqlite/clinic/cursor.c.h | 7 +++++-- Modules/_sqlite/cursor.c | 3 ++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Modules/_sqlite/clinic/cursor.c.h b/Modules/_sqlite/clinic/cursor.c.h index 2d495515d22ef0..0e9ff3aafe87c7 100644 --- a/Modules/_sqlite/clinic/cursor.c.h +++ b/Modules/_sqlite/clinic/cursor.c.h @@ -141,7 +141,10 @@ PyDoc_STRVAR(pysqlite_cursor_fetchmany__doc__, "fetchmany($self, /, size=)\n" "--\n" "\n" -"Fetches several rows from the resultset."); +"Fetches several rows from the resultset.\n" +"\n" +" size\n" +" The number of rows to fetch. Defaults to the cursor\'s arraysize."); #define PYSQLITE_CURSOR_FETCHMANY_METHODDEF \ {"fetchmany", (PyCFunction)(void(*)(void))pysqlite_cursor_fetchmany, METH_FASTCALL|METH_KEYWORDS, pysqlite_cursor_fetchmany__doc__}, @@ -256,4 +259,4 @@ pysqlite_cursor_close(pysqlite_Cursor *self, PyObject *Py_UNUSED(ignored)) { return pysqlite_cursor_close_impl(self); } -/*[clinic end generated code: output=8b5ffd9029d33cd8 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=f4849063bed630ba input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 2b693a17e9b9ca..c210dc407297d6 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -823,13 +823,14 @@ pysqlite_cursor_fetchone_impl(pysqlite_Cursor *self) _sqlite3.Cursor.fetchmany as pysqlite_cursor_fetchmany size as maxrows: int(c_default='self->arraysize', py_default='') = 1 + The number of rows to fetch. Defaults to the cursor's arraysize. Fetches several rows from the resultset. [clinic start generated code]*/ static PyObject * pysqlite_cursor_fetchmany_impl(pysqlite_Cursor *self, int maxrows) -/*[clinic end generated code: output=a8ef31fea64d0906 input=e436f4f150e78b9b]*/ +/*[clinic end generated code: output=a8ef31fea64d0906 input=ed86f9895a4d3796]*/ { PyObject* row; PyObject* list; From bd51d3f46b173abfe16df321cdf5300c751cdc2d Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 13 Jan 2021 23:22:32 +0100 Subject: [PATCH 5/8] Address review: Adjust parameter docstring wording --- Modules/_sqlite/cursor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index c210dc407297d6..e77135f9e4ce1b 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -823,7 +823,7 @@ pysqlite_cursor_fetchone_impl(pysqlite_Cursor *self) _sqlite3.Cursor.fetchmany as pysqlite_cursor_fetchmany size as maxrows: int(c_default='self->arraysize', py_default='') = 1 - The number of rows to fetch. Defaults to the cursor's arraysize. + The default value is set by the Cursor.arraysize attribute. Fetches several rows from the resultset. [clinic start generated code]*/ From 589db0ba2666bfef901484f0d6114c56c022e4ea Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 13 Jan 2021 23:28:51 +0100 Subject: [PATCH 6/8] Update clinic --- Modules/_sqlite/clinic/cursor.c.h | 4 ++-- Modules/_sqlite/cursor.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Modules/_sqlite/clinic/cursor.c.h b/Modules/_sqlite/clinic/cursor.c.h index 0e9ff3aafe87c7..d1fbecc62a114f 100644 --- a/Modules/_sqlite/clinic/cursor.c.h +++ b/Modules/_sqlite/clinic/cursor.c.h @@ -144,7 +144,7 @@ PyDoc_STRVAR(pysqlite_cursor_fetchmany__doc__, "Fetches several rows from the resultset.\n" "\n" " size\n" -" The number of rows to fetch. Defaults to the cursor\'s arraysize."); +" The default value is set by the Cursor.arraysize attribute."); #define PYSQLITE_CURSOR_FETCHMANY_METHODDEF \ {"fetchmany", (PyCFunction)(void(*)(void))pysqlite_cursor_fetchmany, METH_FASTCALL|METH_KEYWORDS, pysqlite_cursor_fetchmany__doc__}, @@ -259,4 +259,4 @@ pysqlite_cursor_close(pysqlite_Cursor *self, PyObject *Py_UNUSED(ignored)) { return pysqlite_cursor_close_impl(self); } -/*[clinic end generated code: output=f4849063bed630ba input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5699aeda4c7577ab input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index e77135f9e4ce1b..1b2ce118976af8 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -830,7 +830,7 @@ Fetches several rows from the resultset. static PyObject * pysqlite_cursor_fetchmany_impl(pysqlite_Cursor *self, int maxrows) -/*[clinic end generated code: output=a8ef31fea64d0906 input=ed86f9895a4d3796]*/ +/*[clinic end generated code: output=a8ef31fea64d0906 input=c527dc13615e01d7]*/ { PyObject* row; PyObject* list; From 834f890a60e508886c0cda61636606500556f890 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 13 Jan 2021 23:40:40 +0100 Subject: [PATCH 7/8] Address review: Remove pydefault='' --- Modules/_sqlite/cursor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 1b2ce118976af8..73a37f43f85b2c 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -822,7 +822,7 @@ pysqlite_cursor_fetchone_impl(pysqlite_Cursor *self) /*[clinic input] _sqlite3.Cursor.fetchmany as pysqlite_cursor_fetchmany - size as maxrows: int(c_default='self->arraysize', py_default='') = 1 + size as maxrows: int(c_default='self->arraysize') = 1 The default value is set by the Cursor.arraysize attribute. Fetches several rows from the resultset. From ac00b5faed60b3ef4f19370a4344d76a4648b204 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Wed, 13 Jan 2021 23:47:17 +0100 Subject: [PATCH 8/8] Update clinic again --- Modules/_sqlite/clinic/cursor.c.h | 4 ++-- Modules/_sqlite/cursor.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Modules/_sqlite/clinic/cursor.c.h b/Modules/_sqlite/clinic/cursor.c.h index d1fbecc62a114f..7a79d74818a2e2 100644 --- a/Modules/_sqlite/clinic/cursor.c.h +++ b/Modules/_sqlite/clinic/cursor.c.h @@ -138,7 +138,7 @@ pysqlite_cursor_fetchone(pysqlite_Cursor *self, PyObject *Py_UNUSED(ignored)) } PyDoc_STRVAR(pysqlite_cursor_fetchmany__doc__, -"fetchmany($self, /, size=)\n" +"fetchmany($self, /, size=1)\n" "--\n" "\n" "Fetches several rows from the resultset.\n" @@ -259,4 +259,4 @@ pysqlite_cursor_close(pysqlite_Cursor *self, PyObject *Py_UNUSED(ignored)) { return pysqlite_cursor_close_impl(self); } -/*[clinic end generated code: output=5699aeda4c7577ab input=a9049054013a1b77]*/ +/*[clinic end generated code: output=6a2d4d49784aa686 input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 73a37f43f85b2c..0852aa940264a2 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -830,7 +830,7 @@ Fetches several rows from the resultset. static PyObject * pysqlite_cursor_fetchmany_impl(pysqlite_Cursor *self, int maxrows) -/*[clinic end generated code: output=a8ef31fea64d0906 input=c527dc13615e01d7]*/ +/*[clinic end generated code: output=a8ef31fea64d0906 input=c26e6ca3f34debd0]*/ { PyObject* row; PyObject* list;