@@ -39,7 +39,7 @@ impl<T: Element> IntoPyArray for Box<[T]> {
3939 fn into_pyarray < ' py > ( self , py : Python < ' py > ) -> & ' py PyArray < Self :: Item , Self :: Dim > {
4040 let len = self . len ( ) ;
4141 let strides = [ mem:: size_of :: < T > ( ) as npy_intp ] ;
42- unsafe { PyArray :: from_boxed_slice ( py, [ len] , strides. as_ptr ( ) , self ) }
42+ unsafe { PyArray :: from_boxed_slice ( py, [ len] , strides. as_ptr ( ) , self , None ) }
4343 }
4444}
4545
@@ -59,10 +59,20 @@ where
5959 type Item = A ;
6060 type Dim = D ;
6161 fn into_pyarray < ' py > ( self , py : Python < ' py > ) -> & ' py PyArray < Self :: Item , Self :: Dim > {
62- let strides = self . npy_strides ( ) ;
63- let dim = self . raw_dim ( ) ;
64- let boxed = self . into_raw_vec ( ) . into_boxed_slice ( ) ;
65- unsafe { PyArray :: from_boxed_slice ( py, dim, strides. as_ptr ( ) , boxed) }
62+ let ( strides, dim) = ( self . npy_strides ( ) , self . raw_dim ( ) ) ;
63+ let orig_ptr = self . as_ptr ( ) ;
64+ let is_empty_or_size0 = self . is_empty ( ) || std:: mem:: size_of :: < Self > ( ) == 0 ;
65+ let vec = self . into_raw_vec ( ) ;
66+ let offset = if is_empty_or_size0 {
67+ 0
68+ } else {
69+ unsafe { orig_ptr. offset_from ( vec. as_ptr ( ) ) as usize }
70+ } ;
71+ let mut boxed_slice = vec. into_boxed_slice ( ) ;
72+ // data_ptr is not always the pointer to the 1st element.
73+ // See https://github.com/PyO3/rust-numpy/issues/182 for the detail.
74+ let data_ptr = unsafe { boxed_slice. as_mut_ptr ( ) . add ( offset) } ;
75+ unsafe { PyArray :: from_boxed_slice ( py, dim, strides. as_ptr ( ) , boxed_slice, Some ( data_ptr) ) }
6676 }
6777}
6878
0 commit comments