Title: [985] trunk: Let single() and variants raise more specific error
Revision
985
Author
cito
Date
2019-04-22 18:07:43 -0400 (Mon, 22 Apr 2019)

Log Message

Let single() and variants raise more specific error

Modified Paths


Diff

Modified: trunk/docs/contents/pg/query.rst (984 => 985)


--- trunk/docs/contents/pg/query.rst	2019-04-22 21:38:23 UTC (rev 984)
+++ trunk/docs/contents/pg/query.rst	2019-04-22 22:07:43 UTC (rev 985)
@@ -244,7 +244,7 @@
 
     :returns: single row from the query results as a tuple of fields
     :rtype: tuple
-	:raises ProgrammingError: result does not have exactly one row
+	:raises InvalidResultError: result does not have exactly one row
     :raises TypeError: too many (any) parameters
     :raises MemoryError: internal memory error
 
@@ -251,7 +251,9 @@
 Returns a single row from the result as a tuple of fields.
 
 This method returns the same single row when called multiple times.
-It raises a ProgrammingError if the result does not have exactly one row.
+It raises an :exc:`pg.InvalidResultError` if the result does not have exactly
+one row. More specifically, this will be of type :exc:`pg.NoResultError` if it
+is empty and of type :exc:`pg.MultipleResultsError` if it has multiple rows.
 
 .. versionadded:: 5.1
 
@@ -261,7 +263,7 @@
 
     :returns: single row from the query results as a dictionary
     :rtype: dict
-	:raises ProgrammingError: result does not have exactly one row
+	:raises InvalidResultError: result does not have exactly one row
     :raises TypeError: too many (any) parameters
     :raises MemoryError: internal memory error
 
@@ -269,7 +271,9 @@
 used as the keys.
 
 This method returns the same single row when called multiple times.
-It raises a ProgrammingError if the result does not have exactly one row.
+It raises an :exc:`pg.InvalidResultError` if the result does not have exactly
+one row. More specifically, this will be of type :exc:`pg.NoResultError` if it
+is empty and of type :exc:`pg.MultipleResultsError` if it has multiple rows.
 
 .. versionadded:: 5.1
 
@@ -279,7 +283,7 @@
 
     :returns: single row from the query results as a named tuple
     :rtype: named tuple
-	:raises ProgrammingError: result does not have exactly one row
+	:raises InvalidResultError: result does not have exactly one row
     :raises TypeError: too many (any) parameters
     :raises MemoryError: internal memory error
 
@@ -290,7 +294,9 @@
 automatically renamed to valid positional names.
 
 This method returns the same single row when called multiple times.
-It raises a ProgrammingError if the result does not have exactly one row.
+It raises an :exc:`pg.InvalidResultError` if the result does not have exactly
+one row. More specifically, this will be of type :exc:`pg.NoResultError` if it
+is empty and of type :exc:`pg.MultipleResultsError` if it has multiple rows.
 
 .. versionadded:: 5.1
 
@@ -300,7 +306,7 @@
 
     :returns: single row from the query results as a scalar value
     :rtype: type of first field
-	:raises ProgrammingError: result does not have exactly one row
+	:raises InvalidResultError: result does not have exactly one row
     :raises TypeError: too many (any) parameters
     :raises MemoryError: internal memory error
 
@@ -307,7 +313,9 @@
 Returns the first field of a single row from the result as a scalar value.
 
 This method returns the same single row as scalar when called multiple times.
-It raises a ProgrammingError if the result does not have exactly one row.
+It raises an :exc:`pg.InvalidResultError` if the result does not have exactly
+one row. More specifically, this will be of type :exc:`pg.NoResultError` if it
+is empty and of type :exc:`pg.MultipleResultsError` if it has multiple rows.
 
 .. versionadded:: 5.1
 

Modified: trunk/pgmodule.c (984 => 985)


--- trunk/pgmodule.c	2019-04-22 21:38:23 UTC (rev 984)
+++ trunk/pgmodule.c	2019-04-22 22:07:43 UTC (rev 985)
@@ -42,7 +42,8 @@
 
 static PyObject *Error, *Warning, *InterfaceError, *DatabaseError,
                 *InternalError, *OperationalError, *ProgrammingError,
-                *IntegrityError, *DataError, *NotSupportedError;
+                *IntegrityError, *DataError, *NotSupportedError,
+                *InvalidResultError, *NoResultError, *MultipleResultsError;
 
 #define _TOSTRING(x) #x
 #define TOSTRING(x) _TOSTRING(x)
@@ -4612,7 +4613,8 @@
 "single() -- Get the result of a query as single row\n\n"
 "The single row from the query result is returned as a tuple of fields.\n"
 "This method returns the same single row when called multiple times.\n"
-"It raises a ProgrammingError if the result does not have exactly one row.\n";
+"It raises an InvalidResultError if the result doesn't have exactly one row,\n"
+"which will be of type NoResultError or MultipleResultsError specifically.\n";
 
 static PyObject *
 query_single(queryObject *self, PyObject *noargs)
@@ -4620,8 +4622,10 @@
     PyObject *row_tuple;
 
     if (self->max_row != 1) {
-        set_error_msg(ProgrammingError,
-            self->max_row ? "Multiple results found" : "No result found");
+        if (self->max_row)
+            set_error_msg(MultipleResultsError, "Multiple results found");
+        else
+            set_error_msg(NoResultError, "No result found");
         return NULL;
     }
 
@@ -4727,7 +4731,8 @@
 "The single row from the query result is returned as a dictionary with\n"
 "the field names used as the keys.\n"
 "This method returns the same single row when called multiple times.\n"
-"It raises a ProgrammingError if the result does not have exactly one row.\n";
+"It raises an InvalidResultError if the result doesn't have exactly one row,\n"
+"which will be of type NoResultError or MultipleResultsError specifically.\n";
 
 static PyObject *
 query_singledict(queryObject *self, PyObject *noargs)
@@ -4735,8 +4740,10 @@
     PyObject *row_dict;
 
     if (self->max_row != 1) {
-        set_error_msg(ProgrammingError,
-            self->max_row ? "Multiple results found" : "No result found");
+        if (self->max_row)
+            set_error_msg(MultipleResultsError, "Multiple results found");
+        else
+            set_error_msg(NoResultError, "No result found");
         return NULL;
     }
 
@@ -4816,7 +4823,8 @@
 "singlenamed() -- Get the result of a query as single row\n\n"
 "The single row from the query result is returned as named tuple of fields.\n"
 "This method returns the same single row when called multiple times.\n"
-"It raises a ProgrammingError if the result does not have exactly one row.\n";
+"It raises an InvalidResultError if the result doesn't have exactly one row,\n"
+"which will be of type NoResultError or MultipleResultsError specifically.\n";
 
 static PyObject *
 query_singlenamed(queryObject *self, PyObject *noargs)
@@ -4826,8 +4834,10 @@
     }
 
     if (self->max_row != 1) {
-        set_error_msg(ProgrammingError,
-            self->max_row ? "Multiple results found" : "No result found");
+        if (self->max_row)
+            set_error_msg(MultipleResultsError, "Multiple results found");
+        else
+            set_error_msg(NoResultError, "No result found");
         return NULL;
     }
 
@@ -4968,7 +4978,8 @@
 "singlescalar() -- Get scalar value from single result of a query\n\n"
 "Returns the first field of the next row from the result as a scalar value.\n"
 "This method returns the same single row when called multiple times.\n"
-"It raises a ProgrammingError if the result does not have exactly one row.\n";
+"It raises an InvalidResultError if the result doesn't have exactly one row,\n"
+"which will be of type NoResultError or MultipleResultsError specifically.\n";
 
 static PyObject *
 query_singlescalar(queryObject *self, PyObject *noargs)
@@ -4981,8 +4992,10 @@
     }
 
     if (self->max_row != 1) {
-        set_error_msg(ProgrammingError,
-            self->max_row ? "Multiple results found" : "No result found");
+        if (self->max_row)
+            set_error_msg(MultipleResultsError, "Multiple results found");
+        else
+            set_error_msg(NoResultError, "No result found");
         return NULL;
     }
 
@@ -6200,35 +6213,50 @@
     Warning = PyErr_NewException("pg.Warning", PyExc_Exception, NULL);
     PyDict_SetItemString(dict, "Warning", Warning);
 
-    InterfaceError = PyErr_NewException("pg.InterfaceError", Error, NULL);
+    InterfaceError = PyErr_NewException(
+        "pg.InterfaceError", Error, NULL);
     PyDict_SetItemString(dict, "InterfaceError", InterfaceError);
 
-    DatabaseError = PyErr_NewException("pg.DatabaseError", Error, NULL);
+    DatabaseError = PyErr_NewException(
+        "pg.DatabaseError", Error, NULL);
     PyDict_SetItemString(dict, "DatabaseError", DatabaseError);
 
-    InternalError =
-        PyErr_NewException("pg.InternalError", DatabaseError, NULL);
+    InternalError = PyErr_NewException(
+        "pg.InternalError", DatabaseError, NULL);
     PyDict_SetItemString(dict, "InternalError", InternalError);
 
-    OperationalError =
-        PyErr_NewException("pg.OperationalError", DatabaseError, NULL);
+    OperationalError = PyErr_NewException(
+        "pg.OperationalError", DatabaseError, NULL);
     PyDict_SetItemString(dict, "OperationalError", OperationalError);
 
-    ProgrammingError =
-        PyErr_NewException("pg.ProgrammingError", DatabaseError, NULL);
+    ProgrammingError = PyErr_NewException(
+        "pg.ProgrammingError", DatabaseError, NULL);
     PyDict_SetItemString(dict, "ProgrammingError", ProgrammingError);
 
-    IntegrityError =
-        PyErr_NewException("pg.IntegrityError", DatabaseError, NULL);
+    IntegrityError = PyErr_NewException(
+        "pg.IntegrityError", DatabaseError, NULL);
     PyDict_SetItemString(dict, "IntegrityError", IntegrityError);
 
-    DataError = PyErr_NewException("pg.DataError", DatabaseError, NULL);
+    DataError = PyErr_NewException(
+        "pg.DataError", DatabaseError, NULL);
     PyDict_SetItemString(dict, "DataError", DataError);
 
-    NotSupportedError =
-        PyErr_NewException("pg.NotSupportedError", DatabaseError, NULL);
+    NotSupportedError = PyErr_NewException(
+        "pg.NotSupportedError", DatabaseError, NULL);
     PyDict_SetItemString(dict, "NotSupportedError", NotSupportedError);
 
+    InvalidResultError = PyErr_NewException(
+        "pg.InvalidResultError", DataError, NULL);
+    PyDict_SetItemString(dict, "InvalidResultError", InvalidResultError);
+
+    NoResultError = PyErr_NewException(
+        "pg.NoResultError", InvalidResultError, NULL);
+    PyDict_SetItemString(dict, "NoResultError", NoResultError);
+
+    MultipleResultsError = PyErr_NewException(
+        "pg.MultipleResultsError", InvalidResultError, NULL);
+    PyDict_SetItemString(dict, "MultipleResultsError", MultipleResultsError);
+
     /* Make the version available */
     s = PyStr_FromString(PyPgVersion);
     PyDict_SetItemString(dict, "version", s);

Modified: trunk/tests/test_classic_connection.py (984 => 985)


--- trunk/tests/test_classic_connection.py	2019-04-22 21:38:23 UTC (rev 984)
+++ trunk/tests/test_classic_connection.py	2019-04-22 22:07:43 UTC (rev 985)
@@ -1361,11 +1361,12 @@
         q = self.c.query("select 0 where false")
         try:
             q.single()
-        except pg.ProgrammingError as e:
-            r = str(e)
+        except pg.InvalidResultError as e:
+            r = e
         else:
             r = None
-        self.assertEqual(r, 'No result found')
+        self.assertIsInstance(r, pg.NoResultError)
+        self.assertEqual(str(r), 'No result found')
 
     def testSingleWithSingleRow(self):
         q = self.c.query("select 1, 2")
@@ -1380,21 +1381,23 @@
         q = self.c.query("select 1, 2 union select 3, 4")
         try:
             q.single()
-        except pg.ProgrammingError as e:
-            r = str(e)
+        except pg.InvalidResultError as e:
+            r = e
         else:
             r = None
-        self.assertEqual(r, 'Multiple results found')
+        self.assertIsInstance(r, pg.MultipleResultsError)
+        self.assertEqual(str(r), 'Multiple results found')
 
     def testSingleDictWithEmptyQuery(self):
         q = self.c.query("select 0 where false")
         try:
             q.singledict()
-        except pg.ProgrammingError as e:
-            r = str(e)
+        except pg.InvalidResultError as e:
+            r = e
         else:
             r = None
-        self.assertEqual(r, 'No result found')
+        self.assertIsInstance(r, pg.NoResultError)
+        self.assertEqual(str(r), 'No result found')
 
     def testSingleDictWithSingleRow(self):
         q = self.c.query("select 1 as one, 2 as two")
@@ -1409,21 +1412,23 @@
         q = self.c.query("select 1, 2 union select 3, 4")
         try:
             q.singledict()
-        except pg.ProgrammingError as e:
-            r = str(e)
+        except pg.InvalidResultError as e:
+            r = e
         else:
             r = None
-        self.assertEqual(r, 'Multiple results found')
+        self.assertIsInstance(r, pg.MultipleResultsError)
+        self.assertEqual(str(r), 'Multiple results found')
 
     def testSingleNamedWithEmptyQuery(self):
         q = self.c.query("select 0 where false")
         try:
             q.singlenamed()
-        except pg.ProgrammingError as e:
-            r = str(e)
+        except pg.InvalidResultError as e:
+            r = e
         else:
             r = None
-        self.assertEqual(r, 'No result found')
+        self.assertIsInstance(r, pg.NoResultError)
+        self.assertEqual(str(r), 'No result found')
 
     def testSingleNamedWithSingleRow(self):
         q = self.c.query("select 1 as one, 2 as two")
@@ -1442,21 +1447,23 @@
         q = self.c.query("select 1, 2 union select 3, 4")
         try:
             q.singlenamed()
-        except pg.ProgrammingError as e:
-            r = str(e)
+        except pg.InvalidResultError as e:
+            r = e
         else:
             r = None
-        self.assertEqual(r, 'Multiple results found')
+        self.assertIsInstance(r, pg.MultipleResultsError)
+        self.assertEqual(str(r), 'Multiple results found')
 
     def testSingleScalarWithEmptyQuery(self):
         q = self.c.query("select 0 where false")
         try:
             q.singlescalar()
-        except pg.ProgrammingError as e:
-            r = str(e)
+        except pg.InvalidResultError as e:
+            r = e
         else:
             r = None
-        self.assertEqual(r, 'No result found')
+        self.assertIsInstance(r, pg.NoResultError)
+        self.assertEqual(str(r), 'No result found')
 
     def testSingleScalarWithSingleRow(self):
         q = self.c.query("select 1, 2")
@@ -1471,11 +1478,12 @@
         q = self.c.query("select 1, 2 union select 3, 4")
         try:
             q.singlescalar()
-        except pg.ProgrammingError as e:
-            r = str(e)
+        except pg.InvalidResultError as e:
+            r = e
         else:
             r = None
-        self.assertEqual(r, 'Multiple results found')
+        self.assertIsInstance(r, pg.MultipleResultsError)
+        self.assertEqual(str(r), 'Multiple results found')
 
     def testScalarResult(self):
         q = self.c.query("select 1, 2 union select 3, 4")

Modified: trunk/tests/test_classic_functions.py (984 => 985)


--- trunk/tests/test_classic_functions.py	2019-04-22 21:38:23 UTC (rev 984)
+++ trunk/tests/test_classic_functions.py	2019-04-22 22:07:43 UTC (rev 985)
@@ -66,6 +66,16 @@
     def testhasPgNotSupportedError(self):
         self.assertTrue(issubclass(pg.NotSupportedError, pg.DatabaseError))
 
+    def testhasPgInvalidResultError(self):
+        self.assertTrue(issubclass(pg.InvalidResultError, pg.DataError))
+
+    def testhasPgNoResultError(self):
+        self.assertTrue(issubclass(pg.NoResultError, pg.InvalidResultError))
+
+    def testhasPgMultipleResultsError(self):
+        self.assertTrue(
+            issubclass(pg.MultipleResultsError, pg.InvalidResultError))
+
     def testhasConnect(self):
         self.assertTrue(callable(pg.connect))
 
_______________________________________________
PyGreSQL mailing list
[email protected]
https://mail.vex.net/mailman/listinfo/pygresql

Reply via email to