@@ -1277,6 +1277,27 @@ mod tests {
12771277 ( c"=d" , Float { bytes : 8 } ) ,
12781278 ( c"=z" , Unknown ) ,
12791279 ( c"=0" , Unknown ) ,
1280+ // bare char (no prefix) goes to native_element_type_from_type_char
1281+ (
1282+ c"b" ,
1283+ SignedInteger {
1284+ bytes : size_of :: < c_schar > ( ) ,
1285+ } ,
1286+ ) ,
1287+ (
1288+ c"B" ,
1289+ UnsignedInteger {
1290+ bytes : size_of :: < c_uchar > ( ) ,
1291+ } ,
1292+ ) ,
1293+ ( c"?" , Bool ) ,
1294+ ( c"f" , Float { bytes : 4 } ) ,
1295+ ( c"d" , Float { bytes : 8 } ) ,
1296+ ( c"z" , Unknown ) ,
1297+ // <, >, ! prefixes go to standard_element_type_from_type_char
1298+ ( c"<i" , SignedInteger { bytes : 4 } ) ,
1299+ ( c">H" , UnsignedInteger { bytes : 2 } ) ,
1300+ ( c"!q" , SignedInteger { bytes : 8 } ) ,
12801301 // unknown prefix -> Unknown
12811302 ( c":b" , Unknown ) ,
12821303 ] {
@@ -1314,6 +1335,7 @@ mod tests {
13141335 assert_eq ! ( slice. len( ) , 5 ) ;
13151336 assert_eq ! ( slice[ 0 ] . get( ) , b'a' ) ;
13161337 assert_eq ! ( slice[ 2 ] . get( ) , b'c' ) ;
1338+ assert_eq ! ( unsafe { * slice[ 0 ] . as_ptr( ) } , b'a' ) ;
13171339
13181340 assert_eq ! ( unsafe { * ( buffer. get_ptr( & [ 1 ] ) . cast:: <u8 >( ) ) } , b'b' ) ;
13191341
@@ -1387,17 +1409,60 @@ mod tests {
13871409 } ) ;
13881410 }
13891411
1412+ #[ test]
1413+ fn test_copy_to_fortran_slice ( ) {
1414+ Python :: attach ( |py| {
1415+ let array = py
1416+ . import ( "array" )
1417+ . unwrap ( )
1418+ . call_method ( "array" , ( "f" , ( 1.0 , 1.5 , 2.0 , 2.5 ) ) , None )
1419+ . unwrap ( ) ;
1420+ let buffer = PyBuffer :: get ( & array) . unwrap ( ) ;
1421+
1422+ // wrong length
1423+ assert ! ( buffer. copy_to_fortran_slice( py, & mut [ 0.0f32 ] ) . is_err( ) ) ;
1424+ // correct length
1425+ let mut arr = [ 0.0f32 ; 4 ] ;
1426+ buffer. copy_to_fortran_slice ( py, & mut arr) . unwrap ( ) ;
1427+ assert_eq ! ( arr, [ 1.0 , 1.5 , 2.0 , 2.5 ] ) ;
1428+ } ) ;
1429+ }
1430+
1431+ #[ test]
1432+ fn test_copy_from_slice_wrong_length ( ) {
1433+ Python :: attach ( |py| {
1434+ let array = py
1435+ . import ( "array" )
1436+ . unwrap ( )
1437+ . call_method ( "array" , ( "f" , ( 1.0 , 1.5 , 2.0 , 2.5 ) ) , None )
1438+ . unwrap ( ) ;
1439+ let buffer = PyBuffer :: get ( & array) . unwrap ( ) ;
1440+ // writable buffer, but wrong length
1441+ assert ! ( !buffer. readonly( ) ) ;
1442+ assert ! ( buffer. copy_from_slice( py, & [ 0.0f32 ; 2 ] ) . is_err( ) ) ;
1443+ assert ! ( buffer. copy_from_fortran_slice( py, & [ 0.0f32 ; 2 ] ) . is_err( ) ) ;
1444+ } ) ;
1445+ }
1446+
13901447 #[ test]
13911448 fn test_untyped_buffer ( ) {
13921449 Python :: attach ( |py| {
13931450 let bytes = PyBytes :: new ( py, b"abcde" ) ;
1394- let untyped = PyUntypedBuffer :: get ( & bytes) . unwrap ( ) ;
1395- assert_eq ! ( untyped. dimensions( ) , 1 ) ;
1396- assert_eq ! ( untyped. item_count( ) , 5 ) ;
1397- assert_eq ! ( untyped. format( ) . to_str( ) . unwrap( ) , "B" ) ;
1398- assert_eq ! ( untyped. shape( ) , [ 5 ] ) ;
1451+ let buffer = PyUntypedBuffer :: get ( & bytes) . unwrap ( ) ;
1452+ assert_eq ! ( buffer. dimensions( ) , 1 ) ;
1453+ assert_eq ! ( buffer. item_count( ) , 5 ) ;
1454+ assert_eq ! ( buffer. format( ) . to_str( ) . unwrap( ) , "B" ) ;
1455+ assert_eq ! ( buffer. shape( ) , [ 5 ] ) ;
1456+ assert ! ( !buffer. buf_ptr( ) . is_null( ) ) ;
1457+ assert_eq ! ( buffer. strides( ) , & [ 1 ] ) ;
1458+ assert_eq ! ( buffer. len_bytes( ) , 5 ) ;
1459+ assert_eq ! ( buffer. item_size( ) , 1 ) ;
1460+ assert ! ( buffer. readonly( ) ) ;
1461+ assert ! ( buffer. suboffsets( ) . is_none( ) ) ;
13991462
1400- let typed: & PyBuffer < u8 > = untyped. as_typed ( ) . unwrap ( ) ;
1463+ assert ! ( format!( "{:?}" , buffer) . starts_with( "PyUntypedBuffer { buf: " ) ) ;
1464+
1465+ let typed: & PyBuffer < u8 > = buffer. as_typed ( ) . unwrap ( ) ;
14011466 assert_eq ! ( typed. dimensions( ) , 1 ) ;
14021467 assert_eq ! ( typed. item_count( ) , 5 ) ;
14031468 assert_eq ! ( typed. format( ) . to_str( ) . unwrap( ) , "B" ) ;
@@ -1502,6 +1567,48 @@ mod tests {
15021567 } ) ;
15031568 }
15041569
1570+ #[ test]
1571+ fn test_typed_buffer_view_with_flags ( ) {
1572+ Python :: attach ( |py| {
1573+ let array = py
1574+ . import ( "array" )
1575+ . unwrap ( )
1576+ . call_method ( "array" , ( "f" , ( 1.0 , 1.5 , 2.0 , 2.5 ) ) , None )
1577+ . unwrap ( ) ;
1578+
1579+ PyBufferView :: < f32 , Known , Unknown , Unknown > :: with_flags (
1580+ & array,
1581+ ffi:: PyBUF_ND ,
1582+ |view| {
1583+ assert_eq ! ( view. item_count( ) , 4 ) ;
1584+ assert_eq ! ( view. format( ) . to_str( ) . unwrap( ) , "f" ) ;
1585+
1586+ let slice = view. as_slice ( py) . unwrap ( ) ;
1587+ assert_eq ! ( slice[ 0 ] . get( ) , 1.0 ) ;
1588+ assert_eq ! ( slice[ 3 ] . get( ) , 2.5 ) ;
1589+
1590+ let mut_slice = view. as_mut_slice ( py) . unwrap ( ) ;
1591+ mut_slice[ 0 ] . set ( 9.0 ) ;
1592+ assert_eq ! ( slice[ 0 ] . get( ) , 9.0 ) ;
1593+ } ,
1594+ )
1595+ . unwrap ( ) ;
1596+ } ) ;
1597+ }
1598+
1599+ #[ test]
1600+ fn test_typed_buffer_view_with_flags_incompatible ( ) {
1601+ Python :: attach ( |py| {
1602+ let bytes = PyBytes :: new ( py, b"abcde" ) ;
1603+ let result = PyBufferView :: < f32 , Known , Unknown , Unknown > :: with_flags (
1604+ & bytes,
1605+ ffi:: PyBUF_ND ,
1606+ |_view| { } ,
1607+ ) ;
1608+ assert ! ( result. is_err( ) ) ;
1609+ } ) ;
1610+ }
1611+
15051612 #[ test]
15061613 fn test_buffer_view_error ( ) {
15071614 Python :: attach ( |py| {
0 commit comments