summaryrefslogtreecommitdiffstats
path: root/Lib/sqlite3
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2021-08-06 18:28:47 (GMT)
committerGitHub <noreply@github.com>2021-08-06 18:28:47 (GMT)
commit7d747f26e6cac9f6891d475f3443441ce947697b (patch)
tree2b21130c1bbc45c410cec55d13bdae26e23df10c /Lib/sqlite3
parent738ac00a08cb6a9d104ec85ccb1a44c2399d6baa (diff)
downloadcpython-7d747f26e6cac9f6891d475f3443441ce947697b.zip
cpython-7d747f26e6cac9f6891d475f3443441ce947697b.tar.gz
cpython-7d747f26e6cac9f6891d475f3443441ce947697b.tar.bz2
bpo-44839: Raise more specific errors in sqlite3 (GH-27613)
MemoryError raised in user-defined functions will now preserve its type. OverflowError will now be converted to DataError. Previously both were converted to OperationalError.
Diffstat (limited to 'Lib/sqlite3')
-rw-r--r--Lib/sqlite3/test/userfunctions.py45
1 files changed, 44 insertions, 1 deletions
diff --git a/Lib/sqlite3/test/userfunctions.py b/Lib/sqlite3/test/userfunctions.py
index b3da3c4..9681dbd 100644
--- a/Lib/sqlite3/test/userfunctions.py
+++ b/Lib/sqlite3/test/userfunctions.py
@@ -23,12 +23,16 @@
import contextlib
import functools
+import gc
import io
+import sys
import unittest
import unittest.mock
-import gc
import sqlite3 as sqlite
+from test.support import bigmemtest
+
+
def with_tracebacks(strings):
"""Convenience decorator for testing callback tracebacks."""
strings.append('Traceback')
@@ -69,6 +73,10 @@ def func_returnlonglong():
return 1<<31
def func_raiseexception():
5/0
+def func_memoryerror():
+ raise MemoryError
+def func_overflowerror():
+ raise OverflowError
def func_isstring(v):
return type(v) is str
@@ -187,6 +195,8 @@ class FunctionTests(unittest.TestCase):
self.con.create_function("returnblob", 0, func_returnblob)
self.con.create_function("returnlonglong", 0, func_returnlonglong)
self.con.create_function("raiseexception", 0, func_raiseexception)
+ self.con.create_function("memoryerror", 0, func_memoryerror)
+ self.con.create_function("overflowerror", 0, func_overflowerror)
self.con.create_function("isstring", 1, func_isstring)
self.con.create_function("isint", 1, func_isint)
@@ -279,6 +289,20 @@ class FunctionTests(unittest.TestCase):
cur.fetchone()
self.assertEqual(str(cm.exception), 'user-defined function raised exception')
+ @with_tracebacks(['func_memoryerror', 'MemoryError'])
+ def test_func_memory_error(self):
+ cur = self.con.cursor()
+ with self.assertRaises(MemoryError):
+ cur.execute("select memoryerror()")
+ cur.fetchone()
+
+ @with_tracebacks(['func_overflowerror', 'OverflowError'])
+ def test_func_overflow_error(self):
+ cur = self.con.cursor()
+ with self.assertRaises(sqlite.DataError):
+ cur.execute("select overflowerror()")
+ cur.fetchone()
+
def test_param_string(self):
cur = self.con.cursor()
for text in ["foo", str()]:
@@ -384,6 +408,25 @@ class FunctionTests(unittest.TestCase):
del x,y
gc.collect()
+ @unittest.skipUnless(sys.maxsize > 2**32, 'requires 64bit platform')
+ @bigmemtest(size=2**31, memuse=3, dry_run=False)
+ def test_large_text(self, size):
+ cur = self.con.cursor()
+ for size in 2**31-1, 2**31:
+ self.con.create_function("largetext", 0, lambda size=size: "b" * size)
+ with self.assertRaises(sqlite.DataError):
+ cur.execute("select largetext()")
+
+ @unittest.skipUnless(sys.maxsize > 2**32, 'requires 64bit platform')
+ @bigmemtest(size=2**31, memuse=2, dry_run=False)
+ def test_large_blob(self, size):
+ cur = self.con.cursor()
+ for size in 2**31-1, 2**31:
+ self.con.create_function("largeblob", 0, lambda size=size: b"b" * size)
+ with self.assertRaises(sqlite.DataError):
+ cur.execute("select largeblob()")
+
+
class AggregateTests(unittest.TestCase):
def setUp(self):
self.con = sqlite.connect(":memory:")