@@ -2238,11 +2238,12 @@ mod _sqlite {
2238
2238
vm : & VirtualMachine ,
2239
2239
) -> PyResult < ( ) > {
2240
2240
let Some ( value) = value else {
2241
- return Err ( vm. new_type_error ( "Blob doesn't support deletion" ) ) ;
2241
+ return Err ( vm. new_type_error ( "Blob doesn't support slice deletion" ) ) ;
2242
2242
} ;
2243
2243
let inner = self . inner ( vm) ?;
2244
2244
2245
2245
if let Some ( index) = needle. try_index_opt ( vm) {
2246
+ // Handle single item assignment: blob[i] = b
2246
2247
let Some ( value) = value. downcast_ref :: < PyInt > ( ) else {
2247
2248
return Err ( vm. new_type_error ( format ! (
2248
2249
"'{}' object cannot be interpreted as an integer" ,
@@ -2255,11 +2256,61 @@ mod _sqlite {
2255
2256
Self :: expect_write ( blob_len, 1 , index, vm) ?;
2256
2257
let ret = inner. blob . write_single ( value, index) ;
2257
2258
self . check ( ret, vm)
2258
- } else if let Some ( _slice) = needle. downcast_ref :: < PySlice > ( ) {
2259
- Err ( vm. new_not_implemented_error ( "Blob slice assignment is not implemented" ) )
2260
- // let blob_len = inner.blob.bytes();
2261
- // let slice = slice.to_saturated(vm)?;
2262
- // let (range, step, length) = slice.adjust_indices(blob_len as usize);
2259
+ } else if let Some ( slice) = needle. downcast_ref :: < PySlice > ( ) {
2260
+ // Handle slice assignment: blob[a:b:c] = b"..."
2261
+ let value_buf = PyBuffer :: try_from_borrowed_object ( vm, & value) ?;
2262
+
2263
+ let buf = value_buf
2264
+ . as_contiguous ( )
2265
+ . ok_or_else ( || vm. new_buffer_error ( "underlying buffer is not C-contiguous" ) ) ?;
2266
+
2267
+ let blob_len = inner. blob . bytes ( ) ;
2268
+ let slice = slice. to_saturated ( vm) ?;
2269
+ let ( range, step, slice_len) = slice. adjust_indices ( blob_len as usize ) ;
2270
+
2271
+ if step == 0 {
2272
+ return Err ( vm. new_value_error ( "slice step cannot be zero" ) ) ;
2273
+ }
2274
+
2275
+ if buf. len ( ) != slice_len {
2276
+ return Err ( vm. new_index_error ( "Blob slice assignment is wrong size" ) ) ;
2277
+ }
2278
+
2279
+ if slice_len == 0 {
2280
+ return Ok ( ( ) ) ;
2281
+ }
2282
+
2283
+ if step == 1 {
2284
+ let ret = inner. blob . write (
2285
+ buf. as_ptr ( ) . cast ( ) ,
2286
+ buf. len ( ) as c_int ,
2287
+ range. start as c_int ,
2288
+ ) ;
2289
+ self . check ( ret, vm)
2290
+ } else {
2291
+ let span_len = range. end - range. start ;
2292
+ let mut temp_buf = vec ! [ 0u8 ; span_len] ;
2293
+
2294
+ let ret = inner. blob . read (
2295
+ temp_buf. as_mut_ptr ( ) . cast ( ) ,
2296
+ span_len as c_int ,
2297
+ range. start as c_int ,
2298
+ ) ;
2299
+ self . check ( ret, vm) ?;
2300
+
2301
+ let mut i_in_temp: usize = 0 ;
2302
+ for i_in_src in 0 ..slice_len {
2303
+ temp_buf[ i_in_temp] = buf[ i_in_src] ;
2304
+ i_in_temp += step as usize ;
2305
+ }
2306
+
2307
+ let ret = inner. blob . write (
2308
+ temp_buf. as_ptr ( ) . cast ( ) ,
2309
+ span_len as c_int ,
2310
+ range. start as c_int ,
2311
+ ) ;
2312
+ self . check ( ret, vm)
2313
+ }
2263
2314
} else {
2264
2315
Err ( vm. new_type_error ( "Blob indices must be integers" ) )
2265
2316
}
0 commit comments