33
33
check_disallow_instantiation ,
34
34
threading_helper ,
35
35
)
36
- from _testcapi import INT_MAX
36
+ from _testcapi import INT_MAX , ULLONG_MAX
37
37
from os import SEEK_SET , SEEK_CUR , SEEK_END
38
38
from test .support .os_helper import TESTFN , unlink , temp_dir
39
39
@@ -1138,6 +1138,13 @@ def test_blob_write_error_length(self):
1138
1138
with self .assertRaisesRegex (ValueError , "data longer than blob" ):
1139
1139
self .blob .write (b"a" * 1000 )
1140
1140
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
+
1141
1148
def test_blob_write_error_row_changed (self ):
1142
1149
self .cx .execute ("update test set b='aaaa' where rowid=1" )
1143
1150
with self .assertRaises (sqlite .OperationalError ):
@@ -1162,12 +1169,127 @@ def test_blob_open_error(self):
1162
1169
with self .assertRaisesRegex (sqlite .OperationalError , regex ):
1163
1170
self .cx .blobopen (* args , ** kwds )
1164
1171
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
+
1165
1287
def test_blob_sequence_not_supported (self ):
1166
- with self .assertRaises (TypeError ):
1288
+ with self .assertRaisesRegex (TypeError , "unsupported operand" ):
1167
1289
self .blob + self .blob
1168
- with self .assertRaises (TypeError ):
1290
+ with self .assertRaisesRegex (TypeError , "unsupported operand" ):
1169
1291
self .blob * 5
1170
- with self .assertRaises (TypeError ):
1292
+ with self .assertRaisesRegex (TypeError , "is not iterable" ):
1171
1293
b"a" in self .blob
1172
1294
1173
1295
def test_blob_context_manager (self ):
@@ -1209,6 +1331,14 @@ def test_blob_closed(self):
1209
1331
blob .__enter__ ()
1210
1332
with self .assertRaisesRegex (sqlite .ProgrammingError , msg ):
1211
1333
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""
1212
1342
1213
1343
def test_blob_closed_db_read (self ):
1214
1344
with memory_database () as cx :
0 commit comments