diff options
Diffstat (limited to 'Lib/test/test_sqlite3/test_dbapi.py')
-rw-r--r-- | Lib/test/test_sqlite3/test_dbapi.py | 138 |
1 files changed, 134 insertions, 4 deletions
diff --git a/Lib/test/test_sqlite3/test_dbapi.py b/Lib/test/test_sqlite3/test_dbapi.py index 79dcb3e..8bfdce2 100644 --- a/Lib/test/test_sqlite3/test_dbapi.py +++ b/Lib/test/test_sqlite3/test_dbapi.py @@ -33,7 +33,7 @@ from test.support import ( check_disallow_instantiation, threading_helper, ) -from _testcapi import INT_MAX +from _testcapi import INT_MAX, ULLONG_MAX from os import SEEK_SET, SEEK_CUR, SEEK_END from test.support.os_helper import TESTFN, unlink, temp_dir @@ -1138,6 +1138,13 @@ class BlobTests(unittest.TestCase): with self.assertRaisesRegex(ValueError, "data longer than blob"): self.blob.write(b"a" * 1000) + self.blob.seek(0, SEEK_SET) + n = len(self.blob) + self.blob.write(b"a" * (n-1)) + self.blob.write(b"a") + with self.assertRaisesRegex(ValueError, "data longer than blob"): + self.blob.write(b"a") + def test_blob_write_error_row_changed(self): self.cx.execute("update test set b='aaaa' where rowid=1") with self.assertRaises(sqlite.OperationalError): @@ -1162,12 +1169,127 @@ class BlobTests(unittest.TestCase): with self.assertRaisesRegex(sqlite.OperationalError, regex): self.cx.blobopen(*args, **kwds) + def test_blob_length(self): + self.assertEqual(len(self.blob), 50) + + def test_blob_get_item(self): + self.assertEqual(self.blob[5], b"b") + self.assertEqual(self.blob[6], b"l") + self.assertEqual(self.blob[7], b"o") + self.assertEqual(self.blob[8], b"b") + self.assertEqual(self.blob[-1], b"!") + + def test_blob_set_item(self): + self.blob[0] = b"b" + expected = b"b" + self.data[1:] + actual = self.cx.execute("select b from test").fetchone()[0] + self.assertEqual(actual, expected) + + def test_blob_set_item_with_offset(self): + self.blob.seek(0, SEEK_END) + self.assertEqual(self.blob.read(), b"") # verify that we're at EOB + self.blob[0] = b"T" + self.blob[-1] = b"." + self.blob.seek(0, SEEK_SET) + expected = b"This blob data string is exactly fifty bytes long." + self.assertEqual(self.blob.read(), expected) + + def test_blob_set_buffer_object(self): + from array import array + self.blob[0] = memoryview(b"1") + self.assertEqual(self.blob[0], b"1") + + self.blob[1] = bytearray(b"2") + self.assertEqual(self.blob[1], b"2") + + self.blob[2] = array("b", [4]) + self.assertEqual(self.blob[2], b"\x04") + + self.blob[0:5] = memoryview(b"12345") + self.assertEqual(self.blob[0:5], b"12345") + + self.blob[0:5] = bytearray(b"23456") + self.assertEqual(self.blob[0:5], b"23456") + + self.blob[0:5] = array("b", [1, 2, 3, 4, 5]) + self.assertEqual(self.blob[0:5], b"\x01\x02\x03\x04\x05") + + def test_blob_set_item_negative_index(self): + self.blob[-1] = b"z" + self.assertEqual(self.blob[-1], b"z") + + def test_blob_get_slice(self): + self.assertEqual(self.blob[5:14], b"blob data") + + def test_blob_get_empty_slice(self): + self.assertEqual(self.blob[5:5], b"") + + def test_blob_get_slice_negative_index(self): + self.assertEqual(self.blob[5:-5], self.data[5:-5]) + + def test_blob_get_slice_with_skip(self): + self.assertEqual(self.blob[0:10:2], b"ti lb") + + def test_blob_set_slice(self): + self.blob[0:5] = b"12345" + expected = b"12345" + self.data[5:] + actual = self.cx.execute("select b from test").fetchone()[0] + self.assertEqual(actual, expected) + + def test_blob_set_empty_slice(self): + self.blob[0:0] = b"" + self.assertEqual(self.blob[:], self.data) + + def test_blob_set_slice_with_skip(self): + self.blob[0:10:2] = b"12345" + actual = self.cx.execute("select b from test").fetchone()[0] + expected = b"1h2s3b4o5 " + self.data[10:] + self.assertEqual(actual, expected) + + def test_blob_mapping_invalid_index_type(self): + msg = "indices must be integers" + with self.assertRaisesRegex(TypeError, msg): + self.blob[5:5.5] + with self.assertRaisesRegex(TypeError, msg): + self.blob[1.5] + with self.assertRaisesRegex(TypeError, msg): + self.blob["a"] = b"b" + + def test_blob_get_item_error(self): + dataset = [len(self.blob), 105, -105] + for idx in dataset: + with self.subTest(idx=idx): + with self.assertRaisesRegex(IndexError, "index out of range"): + self.blob[idx] + with self.assertRaisesRegex(IndexError, "cannot fit 'int'"): + self.blob[ULLONG_MAX] + + def test_blob_set_item_error(self): + with self.assertRaisesRegex(ValueError, "must be a single byte"): + self.blob[0] = b"multiple" + with self.assertRaisesRegex(TypeError, "doesn't support.*deletion"): + del self.blob[0] + with self.assertRaisesRegex(IndexError, "Blob index out of range"): + self.blob[1000] = b"a" + + def test_blob_set_slice_error(self): + with self.assertRaisesRegex(IndexError, "wrong size"): + self.blob[5:10] = b"a" + with self.assertRaisesRegex(IndexError, "wrong size"): + self.blob[5:10] = b"a" * 1000 + with self.assertRaisesRegex(TypeError, "doesn't support.*deletion"): + del self.blob[5:10] + with self.assertRaisesRegex(ValueError, "step cannot be zero"): + self.blob[5:10:0] = b"12345" + with self.assertRaises(BufferError): + self.blob[5:10] = memoryview(b"abcde")[::2] + def test_blob_sequence_not_supported(self): - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, "unsupported operand"): self.blob + self.blob - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, "unsupported operand"): self.blob * 5 - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, "is not iterable"): b"a" in self.blob def test_blob_context_manager(self): @@ -1209,6 +1331,14 @@ class BlobTests(unittest.TestCase): blob.__enter__() with self.assertRaisesRegex(sqlite.ProgrammingError, msg): blob.__exit__(None, None, None) + with self.assertRaisesRegex(sqlite.ProgrammingError, msg): + len(blob) + with self.assertRaisesRegex(sqlite.ProgrammingError, msg): + blob[0] + with self.assertRaisesRegex(sqlite.ProgrammingError, msg): + blob[0:1] + with self.assertRaisesRegex(sqlite.ProgrammingError, msg): + blob[0] = b"" def test_blob_closed_db_read(self): with memory_database() as cx: |