summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorErlend Egeberg Aasland <erlend.aasland@innova.no>2022-03-17 05:58:25 (GMT)
committerGitHub <noreply@github.com>2022-03-17 05:58:25 (GMT)
commit4674fd4e938eb4a29ccd5b12c15455bd2a41c335 (patch)
tree9b6d452caca59b4fa2e3eee150de2d3e098d73fa /Lib
parent96568e995d840c66edb25b6b9d85e4dcccf5a936 (diff)
downloadcpython-4674fd4e938eb4a29ccd5b12c15455bd2a41c335.zip
cpython-4674fd4e938eb4a29ccd5b12c15455bd2a41c335.tar.gz
cpython-4674fd4e938eb4a29ccd5b12c15455bd2a41c335.tar.bz2
bpo-44859: Raise more accurate exceptions in `sqlite3` (GH-27695)
* Improve exception compliance with PEP 249 * Raise InterfaceError instead of ProgrammingError for SQLITE_MISUSE. If SQLITE_MISUSE is raised, it is a sqlite3 module bug. Users of the sqlite3 module are not responsible for using the SQLite C API correctly. * Don't overwrite BufferError with ValueError when conversion to BLOB fails. * Raise ProgrammingError instead of Warning if user tries to execute() more than one SQL statement. * Raise ProgrammingError instead of ValueError if an SQL query contains null characters. * Make sure `_pysqlite_set_result` raises an exception if it returns -1.
Diffstat (limited to 'Lib')
-rw-r--r--Lib/test/test_sqlite3/test_dbapi.py5
-rw-r--r--Lib/test/test_sqlite3/test_regression.py15
-rw-r--r--Lib/test/test_sqlite3/test_userfunctions.py17
3 files changed, 28 insertions, 9 deletions
diff --git a/Lib/test/test_sqlite3/test_dbapi.py b/Lib/test/test_sqlite3/test_dbapi.py
index 4eb4e18..177c2cd 100644
--- a/Lib/test/test_sqlite3/test_dbapi.py
+++ b/Lib/test/test_sqlite3/test_dbapi.py
@@ -652,8 +652,9 @@ class CursorTests(unittest.TestCase):
self.cu.execute("select asdf")
def test_execute_too_much_sql(self):
- with self.assertRaises(sqlite.Warning):
- self.cu.execute("select 5+4; select 4+5")
+ self.assertRaisesRegex(sqlite.ProgrammingError,
+ "You can only execute one statement at a time",
+ self.cu.execute, "select 5+4; select 4+5")
def test_execute_too_much_sql2(self):
self.cu.execute("select 5+4; -- foo bar")
diff --git a/Lib/test/test_sqlite3/test_regression.py b/Lib/test/test_sqlite3/test_regression.py
index 211f763..aebea59 100644
--- a/Lib/test/test_sqlite3/test_regression.py
+++ b/Lib/test/test_sqlite3/test_regression.py
@@ -319,12 +319,15 @@ class RegressionTests(unittest.TestCase):
def test_null_character(self):
# Issue #21147
- con = sqlite.connect(":memory:")
- self.assertRaises(ValueError, con, "\0select 1")
- self.assertRaises(ValueError, con, "select 1\0")
- cur = con.cursor()
- self.assertRaises(ValueError, cur.execute, " \0select 2")
- self.assertRaises(ValueError, cur.execute, "select 2\0")
+ cur = self.con.cursor()
+ queries = ["\0select 1", "select 1\0"]
+ for query in queries:
+ with self.subTest(query=query):
+ self.assertRaisesRegex(sqlite.ProgrammingError, "null char",
+ self.con.execute, query)
+ with self.subTest(query=query):
+ self.assertRaisesRegex(sqlite.ProgrammingError, "null char",
+ cur.execute, query)
def test_surrogates(self):
con = sqlite.connect(":memory:")
diff --git a/Lib/test/test_sqlite3/test_userfunctions.py b/Lib/test/test_sqlite3/test_userfunctions.py
index 2588cae..9070c9e 100644
--- a/Lib/test/test_sqlite3/test_userfunctions.py
+++ b/Lib/test/test_sqlite3/test_userfunctions.py
@@ -196,6 +196,8 @@ class FunctionTests(unittest.TestCase):
self.con.create_function("returnlonglong", 0, func_returnlonglong)
self.con.create_function("returnnan", 0, lambda: float("nan"))
self.con.create_function("returntoolargeint", 0, lambda: 1 << 65)
+ self.con.create_function("return_noncont_blob", 0,
+ lambda: memoryview(b"blob")[::2])
self.con.create_function("raiseexception", 0, func_raiseexception)
self.con.create_function("memoryerror", 0, func_memoryerror)
self.con.create_function("overflowerror", 0, func_overflowerror)
@@ -340,10 +342,17 @@ class FunctionTests(unittest.TestCase):
"select spam(?)", (1 << 65,))
def test_non_contiguous_blob(self):
- self.assertRaisesRegex(ValueError, "could not convert BLOB to buffer",
+ self.assertRaisesRegex(BufferError,
+ "underlying buffer is not C-contiguous",
self.con.execute, "select spam(?)",
(memoryview(b"blob")[::2],))
+ @with_tracebacks(BufferError, regex="buffer.*contiguous")
+ def test_return_non_contiguous_blob(self):
+ with self.assertRaises(sqlite.OperationalError):
+ cur = self.con.execute("select return_noncont_blob()")
+ cur.fetchone()
+
def test_param_surrogates(self):
self.assertRaisesRegex(UnicodeEncodeError, "surrogates not allowed",
self.con.execute, "select spam(?)",
@@ -466,6 +475,12 @@ class FunctionTests(unittest.TestCase):
with self.assertRaises(sqlite.DataError):
cur.execute("select largeblob()")
+ def test_func_return_illegal_value(self):
+ self.con.create_function("badreturn", 0, lambda: self)
+ msg = "user-defined function raised exception"
+ self.assertRaisesRegex(sqlite.OperationalError, msg,
+ self.con.execute, "select badreturn()")
+
class AggregateTests(unittest.TestCase):
def setUp(self):