@@ -5,11 +5,11 @@ use num_bigint::Sign;
5
5
use widestring:: WideCString ;
6
6
7
7
use crate :: builtins:: memory:: { try_buffer_from_object, Buffer } ;
8
- use crate :: builtins:: slice:: PySliceRef ;
8
+ use crate :: builtins:: slice:: PySlice ;
9
9
use crate :: builtins:: { PyBytes , PyInt , PyList , PyStr , PyTypeRef } ;
10
10
use crate :: common:: borrow:: BorrowedValueMut ;
11
11
use crate :: common:: lock:: { PyRwLock , PyRwLockReadGuard , PyRwLockWriteGuard } ;
12
- use crate :: function:: { FuncArgs , OptionalArg } ;
12
+ use crate :: function:: OptionalArg ;
13
13
use crate :: pyobject:: {
14
14
BorrowValue , Either , IdProtocol , PyObjectRef , PyRef , PyResult , PyValue , StaticType ,
15
15
TryFromObject , TypeProtocol ,
@@ -18,8 +18,8 @@ use crate::slots::BufferProtocol;
18
18
use crate :: VirtualMachine ;
19
19
20
20
use crate :: stdlib:: ctypes:: basics:: {
21
- generic_get_buffer, get_size, BorrowValue as BorrowValueCData , BorrowValueMut , PyCData ,
22
- PyCDataFunctions , PyCDataMethods , RawBuffer ,
21
+ default_from_param , generic_get_buffer, get_size, BorrowValue as BorrowValueCData ,
22
+ BorrowValueMut , PyCData , PyCDataFunctions , PyCDataMethods , RawBuffer ,
23
23
} ;
24
24
use crate :: stdlib:: ctypes:: pointer:: PyCPointer ;
25
25
use crate :: stdlib:: ctypes:: primitive:: PySimpleType ;
@@ -169,7 +169,7 @@ fn set_array_value(
169
169
}
170
170
171
171
fn array_get_slice_inner (
172
- slice : PySliceRef ,
172
+ slice : PyRef < PySlice > ,
173
173
vm : & VirtualMachine ,
174
174
) -> PyResult < ( isize , isize , isize ) > {
175
175
let step = slice
@@ -236,11 +236,41 @@ impl BufferProtocol for PyCArray {
236
236
}
237
237
}
238
238
239
- // impl PyCDataMethods for PyCArray {
240
- // fn from_param(zelf: PyRef<Self>, value: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
239
+ impl PyCDataMethods for PyCArray {
240
+ fn from_param (
241
+ zelf : PyRef < Self > ,
242
+ value : PyObjectRef ,
243
+ vm : & VirtualMachine ,
244
+ ) -> PyResult < PyObjectRef > {
245
+ if vm. isinstance ( & value, PyCArray :: static_type ( ) ) ? {
246
+ return Ok ( value) ;
247
+ } ;
248
+
249
+ if vm. obj_len ( & value) ? > zelf. _length_ {
250
+ Err ( vm. new_value_error ( "Invalid length" . to_string ( ) ) )
251
+ } else if zelf. _type_ . _type_ . as_str ( ) == "c"
252
+ && value. clone ( ) . downcast_exact :: < PyBytes > ( vm) . is_err ( )
253
+ {
254
+ Err ( vm. new_value_error ( format ! ( "expected bytes, {} found" , value. class( ) . name) ) )
255
+ } else if zelf. _type_ . _type_ . as_str ( ) == "u"
256
+ && value. clone ( ) . downcast_exact :: < PyStr > ( vm) . is_err ( )
257
+ {
258
+ Err ( vm. new_value_error ( format ! (
259
+ "expected unicode string, {} found" ,
260
+ value. class( ) . name
261
+ ) ) )
262
+ } else if vm. isinstance ( & value, & vm. ctx . types . tuple_type ) ? {
263
+ Ok ( ( ) )
264
+ } else {
265
+ //@TODO: make sure what goes here
266
+ Err ( vm. new_type_error ( "Invalid type" . to_string ( ) ) )
267
+ } ?;
241
268
242
- // }
243
- // }
269
+ PyCArray :: init ( zelf. clone ( ) , value, vm) ?;
270
+
271
+ default_from_param ( zelf. clone_class ( ) , zelf. as_object ( ) . clone ( ) , vm)
272
+ }
273
+ }
244
274
245
275
#[ pyimpl( flags( BASETYPE ) , with( BufferProtocol ) ) ]
246
276
impl PyCArray {
@@ -274,9 +304,31 @@ impl PyCArray {
274
304
}
275
305
276
306
#[ pymethod( magic) ]
277
- pub fn init ( & self , value : FuncArgs , vm : & VirtualMachine ) -> PyResult < ( ) > {
278
- // @TODO
279
- Ok ( ( ) )
307
+ pub fn init ( zelf : PyRef < Self > , value : PyObjectRef , vm : & VirtualMachine ) -> PyResult < ( ) > {
308
+ let value_lenght = vm. obj_len ( & value) ?;
309
+
310
+ if value_lenght < zelf. _length_ {
311
+ let value_vec: Vec < PyObjectRef > = vm. extract_elements ( & value) ?;
312
+ for ( i, v) in value_vec. iter ( ) . enumerate ( ) {
313
+ Self :: setitem ( zelf. clone ( ) , Either :: A ( i as isize ) , v. clone ( ) , vm) ?
314
+ }
315
+ Ok ( ( ) )
316
+ } else if value_lenght == zelf. _length_ {
317
+ let py_slice = Either :: B (
318
+ PySlice {
319
+ start : Some ( vm. new_pyobj ( 0 ) ) ,
320
+ stop : vm. new_pyobj ( zelf. _length_ ) ,
321
+ step : None ,
322
+ }
323
+ . into_ref ( vm) ,
324
+ ) ;
325
+
326
+ Self :: setitem ( zelf, py_slice, value, vm)
327
+ } else {
328
+ Err ( vm. new_value_error (
329
+ "number of values is greater than the size of the array" . to_string ( ) ,
330
+ ) )
331
+ }
280
332
}
281
333
282
334
#[ pyproperty( name = "value" ) ]
@@ -440,7 +492,7 @@ impl PyCArray {
440
492
#[ pymethod( magic) ]
441
493
fn getitem (
442
494
zelf : PyRef < Self > ,
443
- k_or_idx : Either < isize , PySliceRef > ,
495
+ k_or_idx : Either < isize , PyRef < PySlice > > ,
444
496
vm : & VirtualMachine ,
445
497
) -> PyResult {
446
498
let buffer = try_buffer_from_object ( vm, zelf. as_object ( ) ) ?;
@@ -484,7 +536,7 @@ impl PyCArray {
484
536
#[ pymethod( magic) ]
485
537
fn setitem (
486
538
zelf : PyRef < Self > ,
487
- k_or_idx : Either < isize , PySliceRef > ,
539
+ k_or_idx : Either < isize , PyRef < PySlice > > ,
488
540
obj : PyObjectRef ,
489
541
vm : & VirtualMachine ,
490
542
) -> PyResult < ( ) > {
@@ -511,7 +563,7 @@ impl PyCArray {
511
563
let values: Vec < PyObjectRef > = vm. extract_elements ( & obj) ?;
512
564
513
565
if values. len ( ) != slice_length {
514
- Err ( vm. new_value_error ( "Can only assign sequence of same size" . to_string ( ) ) )
566
+ Err ( vm. new_value_error ( "can only assign sequence of same size" . to_string ( ) ) )
515
567
} else {
516
568
let mut cur = start as usize ;
517
569
@@ -550,7 +602,7 @@ impl PyCDataFunctions for PyCArray {
550
602
. into_option ( )
551
603
. map_or ( Ok ( 0 ) , |o| usize:: try_from_object ( vm, o) ) ?;
552
604
553
- if off_set > zelf. _length_ {
605
+ if off_set > zelf. _length_ * get_size ( zelf . _type_ . _type_ . as_str ( ) ) {
554
606
Err ( vm. new_index_error ( "offset out of bounds" . to_string ( ) ) )
555
607
} else {
556
608
let guard = zelf. borrow_value ( ) ;
0 commit comments