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.
This commit is contained in:
Erlend Egeberg Aasland 2022-03-17 06:58:25 +01:00 committed by GitHub
parent 96568e995d
commit 4674fd4e93
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 45 additions and 14 deletions

View file

@ -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):