@@ -2238,11 +2238,12 @@ mod _sqlite {
22382238 vm : & VirtualMachine ,
22392239 ) -> PyResult < ( ) > {
22402240 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" ) ) ;
22422242 } ;
22432243 let inner = self . inner ( vm) ?;
22442244
22452245 if let Some ( index) = needle. try_index_opt ( vm) {
2246+ // Handle single item assignment: blob[i] = b
22462247 let Some ( value) = value. downcast_ref :: < PyInt > ( ) else {
22472248 return Err ( vm. new_type_error ( format ! (
22482249 "'{}' object cannot be interpreted as an integer" ,
@@ -2255,11 +2256,61 @@ mod _sqlite {
22552256 Self :: expect_write ( blob_len, 1 , index, vm) ?;
22562257 let ret = inner. blob . write_single ( value, index) ;
22572258 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+ }
22632314 } else {
22642315 Err ( vm. new_type_error ( "Blob indices must be integers" ) )
22652316 }
0 commit comments