[Python-checkins] cpython (merge 3.4 -> default): (Merge 3.4) Issue #21858: Better handling of Python exceptions in the sqlite3

victor.stinner python-checkins at python.org
Thu Jun 26 23:34:27 CEST 2014


http://hg.python.org/cpython/rev/169171da66fa
changeset:   91433:169171da66fa
parent:      91430:bbb28082d7b4
parent:      91432:62612b195cb5
user:        Victor Stinner <victor.stinner at gmail.com>
date:        Thu Jun 26 23:33:34 2014 +0200
summary:
  (Merge 3.4) Issue #21858: Better handling of Python exceptions in the sqlite3
module.

files:
  Misc/NEWS                |   2 +
  Modules/_sqlite/cursor.c |  42 +++++++++++++++++----------
  2 files changed, 28 insertions(+), 16 deletions(-)


diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -103,6 +103,8 @@
 Library
 -------
 
+- Issue #21858: Better handling of Python exceptions in the sqlite3 module.
+
 - Issue #21476: Make sure the email.parser.BytesParser TextIOWrapper is
   discarded after parsing, so the input file isn't unexpectedly closed.
 
diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c
--- a/Modules/_sqlite/cursor.c
+++ b/Modules/_sqlite/cursor.c
@@ -289,9 +289,8 @@
     Py_END_ALLOW_THREADS
 
     row = PyTuple_New(numcols);
-    if (!row) {
+    if (!row)
         return NULL;
-    }
 
     for (i = 0; i < numcols; i++) {
         if (self->connection->detect_types) {
@@ -311,14 +310,12 @@
                 converted = Py_None;
             } else {
                 item = PyBytes_FromStringAndSize(val_str, nbytes);
-                if (!item) {
-                    return NULL;
-                }
+                if (!item)
+                    goto error;
                 converted = PyObject_CallFunction(converter, "O", item);
                 Py_DECREF(item);
-                if (!converted) {
+                if (!converted)
                     break;
-                }
             }
         } else {
             Py_BEGIN_ALLOW_THREADS
@@ -374,9 +371,8 @@
                 nbytes = sqlite3_column_bytes(self->statement->st, i);
                 buffer = PyBytes_FromStringAndSize(
                     sqlite3_column_blob(self->statement->st, i), nbytes);
-                if (!buffer) {
+                if (!buffer)
                     break;
-                }
                 converted = buffer;
             }
         }
@@ -389,12 +385,14 @@
         }
     }
 
-    if (PyErr_Occurred()) {
-        Py_DECREF(row);
-        row = NULL;
-    }
+    if (PyErr_Occurred())
+        goto error;
 
     return row;
+
+error:
+    Py_DECREF(row);
+    return NULL;
 }
 
 /*
@@ -612,6 +610,10 @@
         while (1) {
             /* Actually execute the SQL statement. */
             rc = pysqlite_step(self->statement->st, self->connection);
+            if (PyErr_Occurred()) {
+                (void)pysqlite_statement_reset(self->statement);
+                goto error;
+            }
             if (rc == SQLITE_DONE ||  rc == SQLITE_ROW) {
                 /* If it worked, let's get out of the loop */
                 break;
@@ -685,6 +687,8 @@
             }
 
             self->next_row = _pysqlite_fetch_one_row(self);
+            if (self->next_row == NULL)
+                goto error;
         } else if (rc == SQLITE_DONE && !multiple) {
             pysqlite_statement_reset(self->statement);
             Py_CLEAR(self->statement);
@@ -807,7 +811,10 @@
         rc = SQLITE_ROW;
         while (rc == SQLITE_ROW) {
             rc = pysqlite_step(statement, self->connection);
-            /* TODO: we probably need more error handling here */
+            if (PyErr_Occurred()) {
+                (void)sqlite3_finalize(statement);
+                goto error;
+            }
         }
 
         if (rc != SQLITE_DONE) {
@@ -884,6 +891,11 @@
 
     if (self->statement) {
         rc = pysqlite_step(self->statement->st, self->connection);
+        if (PyErr_Occurred()) {
+            (void)pysqlite_statement_reset(self->statement);
+            Py_DECREF(next_row);
+            return NULL;
+        }
         if (rc != SQLITE_DONE && rc != SQLITE_ROW) {
             (void)pysqlite_statement_reset(self->statement);
             Py_DECREF(next_row);
@@ -895,8 +907,6 @@
             self->next_row = _pysqlite_fetch_one_row(self);
             if (self->next_row == NULL) {
                 (void)pysqlite_statement_reset(self->statement);
-                Py_DECREF(next_row);
-                _pysqlite_seterror(self->connection->db, NULL);
                 return NULL;
             }
         }

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list