3333 check_disallow_instantiation ,
3434 threading_helper ,
3535)
36- from _testcapi import INT_MAX
36+ from _testcapi import INT_MAX , ULLONG_MAX
3737from os import SEEK_SET , SEEK_CUR , SEEK_END
3838from test .support .os_helper import TESTFN , unlink , temp_dir
3939
@@ -1138,6 +1138,13 @@ def test_blob_write_error_length(self):
11381138 with self .assertRaisesRegex (ValueError , "data longer than blob" ):
11391139 self .blob .write (b"a" * 1000 )
11401140
1141+ self .blob .seek (0 , SEEK_SET )
1142+ n = len (self .blob )
1143+ self .blob .write (b"a" * (n - 1 ))
1144+ self .blob .write (b"a" )
1145+ with self .assertRaisesRegex (ValueError , "data longer than blob" ):
1146+ self .blob .write (b"a" )
1147+
11411148 def test_blob_write_error_row_changed (self ):
11421149 self .cx .execute ("update test set b='aaaa' where rowid=1" )
11431150 with self .assertRaises (sqlite .OperationalError ):
@@ -1162,12 +1169,127 @@ def test_blob_open_error(self):
11621169 with self .assertRaisesRegex (sqlite .OperationalError , regex ):
11631170 self .cx .blobopen (* args , ** kwds )
11641171
1172+ def test_blob_length (self ):
1173+ self .assertEqual (len (self .blob ), 50 )
1174+
1175+ def test_blob_get_item (self ):
1176+ self .assertEqual (self .blob [5 ], b"b" )
1177+ self .assertEqual (self .blob [6 ], b"l" )
1178+ self .assertEqual (self .blob [7 ], b"o" )
1179+ self .assertEqual (self .blob [8 ], b"b" )
1180+ self .assertEqual (self .blob [- 1 ], b"!" )
1181+
1182+ def test_blob_set_item (self ):
1183+ self .blob [0 ] = b"b"
1184+ expected = b"b" + self .data [1 :]
1185+ actual = self .cx .execute ("select b from test" ).fetchone ()[0 ]
1186+ self .assertEqual (actual , expected )
1187+
1188+ def test_blob_set_item_with_offset (self ):
1189+ self .blob .seek (0 , SEEK_END )
1190+ self .assertEqual (self .blob .read (), b"" ) # verify that we're at EOB
1191+ self .blob [0 ] = b"T"
1192+ self .blob [- 1 ] = b"."
1193+ self .blob .seek (0 , SEEK_SET )
1194+ expected = b"This blob data string is exactly fifty bytes long."
1195+ self .assertEqual (self .blob .read (), expected )
1196+
1197+ def test_blob_set_buffer_object (self ):
1198+ from array import array
1199+ self .blob [0 ] = memoryview (b"1" )
1200+ self .assertEqual (self .blob [0 ], b"1" )
1201+
1202+ self .blob [1 ] = bytearray (b"2" )
1203+ self .assertEqual (self .blob [1 ], b"2" )
1204+
1205+ self .blob [2 ] = array ("b" , [4 ])
1206+ self .assertEqual (self .blob [2 ], b"\x04 " )
1207+
1208+ self .blob [0 :5 ] = memoryview (b"12345" )
1209+ self .assertEqual (self .blob [0 :5 ], b"12345" )
1210+
1211+ self .blob [0 :5 ] = bytearray (b"23456" )
1212+ self .assertEqual (self .blob [0 :5 ], b"23456" )
1213+
1214+ self .blob [0 :5 ] = array ("b" , [1 , 2 , 3 , 4 , 5 ])
1215+ self .assertEqual (self .blob [0 :5 ], b"\x01 \x02 \x03 \x04 \x05 " )
1216+
1217+ def test_blob_set_item_negative_index (self ):
1218+ self .blob [- 1 ] = b"z"
1219+ self .assertEqual (self .blob [- 1 ], b"z" )
1220+
1221+ def test_blob_get_slice (self ):
1222+ self .assertEqual (self .blob [5 :14 ], b"blob data" )
1223+
1224+ def test_blob_get_empty_slice (self ):
1225+ self .assertEqual (self .blob [5 :5 ], b"" )
1226+
1227+ def test_blob_get_slice_negative_index (self ):
1228+ self .assertEqual (self .blob [5 :- 5 ], self .data [5 :- 5 ])
1229+
1230+ def test_blob_get_slice_with_skip (self ):
1231+ self .assertEqual (self .blob [0 :10 :2 ], b"ti lb" )
1232+
1233+ def test_blob_set_slice (self ):
1234+ self .blob [0 :5 ] = b"12345"
1235+ expected = b"12345" + self .data [5 :]
1236+ actual = self .cx .execute ("select b from test" ).fetchone ()[0 ]
1237+ self .assertEqual (actual , expected )
1238+
1239+ def test_blob_set_empty_slice (self ):
1240+ self .blob [0 :0 ] = b""
1241+ self .assertEqual (self .blob [:], self .data )
1242+
1243+ def test_blob_set_slice_with_skip (self ):
1244+ self .blob [0 :10 :2 ] = b"12345"
1245+ actual = self .cx .execute ("select b from test" ).fetchone ()[0 ]
1246+ expected = b"1h2s3b4o5 " + self .data [10 :]
1247+ self .assertEqual (actual , expected )
1248+
1249+ def test_blob_mapping_invalid_index_type (self ):
1250+ msg = "indices must be integers"
1251+ with self .assertRaisesRegex (TypeError , msg ):
1252+ self .blob [5 :5.5 ]
1253+ with self .assertRaisesRegex (TypeError , msg ):
1254+ self .blob [1.5 ]
1255+ with self .assertRaisesRegex (TypeError , msg ):
1256+ self .blob ["a" ] = b"b"
1257+
1258+ def test_blob_get_item_error (self ):
1259+ dataset = [len (self .blob ), 105 , - 105 ]
1260+ for idx in dataset :
1261+ with self .subTest (idx = idx ):
1262+ with self .assertRaisesRegex (IndexError , "index out of range" ):
1263+ self .blob [idx ]
1264+ with self .assertRaisesRegex (IndexError , "cannot fit 'int'" ):
1265+ self .blob [ULLONG_MAX ]
1266+
1267+ def test_blob_set_item_error (self ):
1268+ with self .assertRaisesRegex (ValueError , "must be a single byte" ):
1269+ self .blob [0 ] = b"multiple"
1270+ with self .assertRaisesRegex (TypeError , "doesn't support.*deletion" ):
1271+ del self .blob [0 ]
1272+ with self .assertRaisesRegex (IndexError , "Blob index out of range" ):
1273+ self .blob [1000 ] = b"a"
1274+
1275+ def test_blob_set_slice_error (self ):
1276+ with self .assertRaisesRegex (IndexError , "wrong size" ):
1277+ self .blob [5 :10 ] = b"a"
1278+ with self .assertRaisesRegex (IndexError , "wrong size" ):
1279+ self .blob [5 :10 ] = b"a" * 1000
1280+ with self .assertRaisesRegex (TypeError , "doesn't support.*deletion" ):
1281+ del self .blob [5 :10 ]
1282+ with self .assertRaisesRegex (ValueError , "step cannot be zero" ):
1283+ self .blob [5 :10 :0 ] = b"12345"
1284+ with self .assertRaises (BufferError ):
1285+ self .blob [5 :10 ] = memoryview (b"abcde" )[::2 ]
1286+
11651287 def test_blob_sequence_not_supported (self ):
1166- with self .assertRaises (TypeError ):
1288+ with self .assertRaisesRegex (TypeError , "unsupported operand" ):
11671289 self .blob + self .blob
1168- with self .assertRaises (TypeError ):
1290+ with self .assertRaisesRegex (TypeError , "unsupported operand" ):
11691291 self .blob * 5
1170- with self .assertRaises (TypeError ):
1292+ with self .assertRaisesRegex (TypeError , "is not iterable" ):
11711293 b"a" in self .blob
11721294
11731295 def test_blob_context_manager (self ):
@@ -1209,6 +1331,14 @@ def test_blob_closed(self):
12091331 blob .__enter__ ()
12101332 with self .assertRaisesRegex (sqlite .ProgrammingError , msg ):
12111333 blob .__exit__ (None , None , None )
1334+ with self .assertRaisesRegex (sqlite .ProgrammingError , msg ):
1335+ len (blob )
1336+ with self .assertRaisesRegex (sqlite .ProgrammingError , msg ):
1337+ blob [0 ]
1338+ with self .assertRaisesRegex (sqlite .ProgrammingError , msg ):
1339+ blob [0 :1 ]
1340+ with self .assertRaisesRegex (sqlite .ProgrammingError , msg ):
1341+ blob [0 ] = b""
12121342
12131343 def test_blob_closed_db_read (self ):
12141344 with memory_database () as cx :
0 commit comments