diff options
author | Erlend Egeberg Aasland <erlend.aasland@innova.no> | 2022-03-17 05:58:25 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-17 05:58:25 (GMT) |
commit | 4674fd4e938eb4a29ccd5b12c15455bd2a41c335 (patch) | |
tree | 9b6d452caca59b4fa2e3eee150de2d3e098d73fa /Lib | |
parent | 96568e995d840c66edb25b6b9d85e4dcccf5a936 (diff) | |
download | cpython-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.py | 5 | ||||
-rw-r--r-- | Lib/test/test_sqlite3/test_regression.py | 15 | ||||
-rw-r--r-- | Lib/test/test_sqlite3/test_userfunctions.py | 17 |
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): |