@@ -12,7 +12,7 @@ use std::{iter::ExactSizeIterator, marker::PhantomData};
1212use  crate :: convert:: { IntoPyArray ,  NpyIndex ,  ToNpyDims ,  ToPyArray } ; 
1313use  crate :: error:: { FromVecError ,  NotContiguousError ,  ShapeError } ; 
1414use  crate :: slice_box:: SliceBox ; 
15- use  crate :: types:: { NpyDataType ,   TypeNum } ; 
15+ use  crate :: types:: Element ; 
1616
1717/// A safe, static-typed interface for 
1818/// [NumPy ndarray](https://numpy.org/doc/stable/reference/arrays.ndarray.html). 
@@ -46,7 +46,7 @@ use crate::types::{NpyDataType, TypeNum};
4646/// `PyArray` has 2 type parametes `T` and `D`. `T` represents its data type like 
4747/// [`f32`](https://doc.rust-lang.org/std/primitive.f32.html), and `D` represents its dimension. 
4848/// 
49- /// All data types you can use implements [TypeNum ](../types/trait.TypeNum .html). 
49+ /// All data types you can use implements [Element ](../types/trait.Element .html). 
5050/// 
5151/// Dimensions are represented by ndarray's 
5252/// [Dimension](https://docs.rs/ndarray/latest/ndarray/trait.Dimension.html) trait. 
@@ -117,7 +117,7 @@ impl<'a, T, D> std::convert::From<&'a PyArray<T, D>> for &'a PyAny {
117117    } 
118118} 
119119
120- impl < ' a ,  T :  TypeNum ,  D :  Dimension >  FromPyObject < ' a >  for  & ' a  PyArray < T ,  D >  { 
120+ impl < ' a ,  T :  Element ,  D :  Dimension >  FromPyObject < ' a >  for  & ' a  PyArray < T ,  D >  { 
121121    // here we do type-check three times 
122122    // 1. Checks if the object is PyArray 
123123    // 2. Checks if the data type of the array is T 
@@ -292,34 +292,27 @@ impl<T, D> PyArray<T, D> {
292292        self . len ( )  == 0 
293293    } 
294294
295-     fn  typenum ( & self )  -> i32  { 
295+     fn  strides_usize ( & self )  -> & [ usize ]  { 
296+         let  n = self . ndim ( ) ; 
297+         let  ptr = self . as_array_ptr ( ) ; 
296298        unsafe  { 
297-             let  descr  = ( * self . as_array_ptr ( ) ) . descr ; 
298-             ( * descr ) . type_num 
299+             let  p  = ( * ptr ) . strides ; 
300+             slice :: from_raw_parts ( p  as   * const   _ ,  n ) 
299301        } 
300302    } 
301303
302304    /// Returns the pointer to the first element of the inner array. 
303305     pub ( crate )  unsafe  fn  data ( & self )  -> * mut  T  { 
304306        let  ptr = self . as_array_ptr ( ) ; 
305-         ( * ptr) . data  as  * mut  T 
307+         ( * ptr) . data  as  * mut  _ 
306308    } 
307309
308310    pub ( crate )  unsafe  fn  copy_ptr ( & self ,  other :  * const  T ,  len :  usize )  { 
309311        ptr:: copy_nonoverlapping ( other,  self . data ( ) ,  len) 
310312    } 
311- 
312-     fn  strides_usize ( & self )  -> & [ usize ]  { 
313-         let  n = self . ndim ( ) ; 
314-         let  ptr = self . as_array_ptr ( ) ; 
315-         unsafe  { 
316-             let  p = ( * ptr) . strides ; 
317-             slice:: from_raw_parts ( p as  * const  _ ,  n) 
318-         } 
319-     } 
320313} 
321314
322- impl < T :  TypeNum ,  D :  Dimension >  PyArray < T ,  D >  { 
315+ impl < T :  Element ,  D :  Dimension >  PyArray < T ,  D >  { 
323316    /// Same as [shape](#method.shape), but returns `D` 
324317     #[ inline( always) ]  
325318    pub  fn  dims ( & self )  -> D  { 
@@ -369,7 +362,7 @@ impl<T: TypeNum, D: Dimension> PyArray<T, D> {
369362            PY_ARRAY_API . get_type_object ( npyffi:: ArrayType :: PyArray_Type ) , 
370363            dims. ndim_cint ( ) , 
371364            dims. as_dims_ptr ( ) , 
372-             T :: typenum_default ( ) , 
365+             T :: ffi_dtype ( )   as   i32 , 
373366            strides as  * mut  _ ,  // strides 
374367            ptr:: null_mut ( ) ,    // data 
375368            0 ,                  // itemsize 
@@ -398,7 +391,7 @@ impl<T: TypeNum, D: Dimension> PyArray<T, D> {
398391            PY_ARRAY_API . get_type_object ( npyffi:: ArrayType :: PyArray_Type ) , 
399392            dims. ndim_cint ( ) , 
400393            dims. as_dims_ptr ( ) , 
401-             T :: typenum_default ( ) , 
394+             T :: ffi_dtype ( )   as   i32 , 
402395            strides as  * mut  _ ,           // strides 
403396            data_ptr as  _ ,               // data 
404397            mem:: size_of :: < T > ( )  as  i32 ,  // itemsize 
@@ -430,7 +423,7 @@ impl<T: TypeNum, D: Dimension> PyArray<T, D> {
430423    { 
431424        let  dims = dims. into_dimension ( ) ; 
432425        unsafe  { 
433-             let  descr = PY_ARRAY_API . PyArray_DescrFromType ( T :: typenum_default ( ) ) ; 
426+             let  descr = PY_ARRAY_API . PyArray_DescrFromType ( T :: ffi_dtype ( )   as   i32 ) ; 
434427            let  ptr = PY_ARRAY_API . PyArray_Zeros ( 
435428                dims. ndim_cint ( ) , 
436429                dims. as_dims_ptr ( ) , 
@@ -480,26 +473,6 @@ impl<T: TypeNum, D: Dimension> PyArray<T, D> {
480473        } 
481474    } 
482475
483-     /// Construct PyArray from `ndarray::ArrayBase`. 
484-      /// 
485-      /// This method allocates memory in Python's heap via numpy api, and then copies all elements 
486-      /// of the array there. 
487-      /// 
488-      /// # Example 
489-      /// ``` 
490-      /// # #[macro_use] extern crate ndarray; 
491-      /// use numpy::PyArray; 
492-      /// let gil = pyo3::Python::acquire_gil(); 
493-      /// let pyarray = PyArray::from_array(gil.python(), &array![[1, 2], [3, 4]]); 
494-      /// assert_eq!(pyarray.readonly().as_array(), array![[1, 2], [3, 4]]); 
495-      /// ``` 
496-      pub  fn  from_array < ' py ,  S > ( py :  Python < ' py > ,  arr :  & ArrayBase < S ,  D > )  -> & ' py  Self 
497-     where 
498-         S :  Data < Elem  = T > , 
499-     { 
500-         ToPyArray :: to_pyarray ( arr,  py) 
501-     } 
502- 
503476    /// Construct PyArray from 
504477     /// [`ndarray::Array`](https://docs.rs/ndarray/latest/ndarray/type.Array.html). 
505478     /// 
@@ -518,25 +491,6 @@ impl<T: TypeNum, D: Dimension> PyArray<T, D> {
518491        IntoPyArray :: into_pyarray ( arr,  py) 
519492    } 
520493
521-     /// Get the immutable view of the internal data of `PyArray`, as 
522-      /// [`ndarray::ArrayView`](https://docs.rs/ndarray/latest/ndarray/type.ArrayView.html). 
523-      /// 
524-      /// # Safety 
525-      /// If the internal array is not readonly and can be mutated from Python code, 
526-      /// holding the `ArrayView` might cause undefined behavior. 
527-      pub  unsafe  fn  as_array ( & self )  -> ArrayView < ' _ ,  T ,  D >  { 
528-         ArrayView :: from_shape_ptr ( self . ndarray_shape ( ) ,  self . data ( ) ) 
529-     } 
530- 
531-     /// Returns the internal array as `ArrayViewMut`. See also [`as_array`](#method.as_array). 
532-      /// 
533-      /// # Safety 
534-      /// If another reference to the internal data exists(e.g., `&[T]` or `ArrayView`), 
535-      /// it might cause undefined behavior. 
536-      pub  unsafe  fn  as_array_mut ( & self )  -> ArrayViewMut < ' _ ,  T ,  D >  { 
537-         ArrayViewMut :: from_shape_ptr ( self . ndarray_shape ( ) ,  self . data ( ) ) 
538-     } 
539- 
540494    /// Get an immutable reference of a specified element, with checking the passed index is valid. 
541495     /// 
542496     /// See [NpyIndex](../convert/trait.NpyIndex.html) for what types you can use as index. 
@@ -608,7 +562,7 @@ impl<T: TypeNum, D: Dimension> PyArray<T, D> {
608562        Idx :  NpyIndex < Dim  = D > , 
609563    { 
610564        let  offset = index. get_unchecked :: < T > ( self . strides ( ) ) ; 
611-         & mut  * ( self . data ( ) . offset ( offset)  as  * mut  T ) 
565+         & mut  * ( self . data ( ) . offset ( offset)  as  * mut  _ ) 
612566    } 
613567
614568    /// Get dynamic dimensioned array from fixed dimension array. 
@@ -620,35 +574,14 @@ impl<T: TypeNum, D: Dimension> PyArray<T, D> {
620574    } 
621575
622576    fn  type_check ( & self )  -> Result < ( ) ,  ShapeError >  { 
623-         let  truth = self . typenum ( ) ; 
577+         let  truth = unsafe   {   ( * ( * self . as_array_ptr ( ) ) . descr ) . type_num   } ; 
624578        let  dim = self . shape ( ) . len ( ) ; 
625-         let  dim_ok = D :: NDIM . map ( |n| n == dim) . unwrap_or ( true ) ; 
626-         if  T :: is_same_type ( truth)  && dim_ok { 
579+         if  T :: is_same_type ( truth)  && D :: NDIM . map ( |n| n == dim) . unwrap_or ( true )  { 
627580            Ok ( ( ) ) 
628581        }  else  { 
629-             Err ( ShapeError :: new ( truth,  dim,  T :: npy_data_type ( ) ,  D :: NDIM ) ) 
582+             Err ( ShapeError :: new ( truth,  dim,  T :: DATA_TYPE ,  D :: NDIM ) ) 
630583        } 
631584    } 
632- } 
633- 
634- impl < T :  Clone  + TypeNum ,  D :  Dimension >  PyArray < T ,  D >  { 
635-     /// Get a copy of `PyArray` as 
636-      /// [`ndarray::Array`](https://docs.rs/ndarray/latest/ndarray/type.Array.html). 
637-      /// 
638-      /// # Example 
639-      /// ``` 
640-      /// # #[macro_use] extern crate ndarray; 
641-      /// use numpy::PyArray; 
642-      /// let gil = pyo3::Python::acquire_gil(); 
643-      /// let py_array = PyArray::arange(gil.python(), 0, 4, 1).reshape([2, 2]).unwrap(); 
644-      /// assert_eq!( 
645-      ///     py_array.to_owned_array(), 
646-      ///     array![[0, 1], [2, 3]] 
647-      /// ) 
648-      /// ``` 
649-      pub  fn  to_owned_array ( & self )  -> Array < T ,  D >  { 
650-         unsafe  {  self . as_array ( )  } . to_owned ( ) 
651-     } 
652585
653586    /// Returns the copy of the internal data of `PyArray` to `Vec`. 
654587     /// 
@@ -672,9 +605,66 @@ impl<T: Clone + TypeNum, D: Dimension> PyArray<T, D> {
672605     pub  fn  to_vec ( & self )  -> Result < Vec < T > ,  NotContiguousError >  { 
673606        unsafe  {  self . as_slice ( )  } . map ( ToOwned :: to_owned) 
674607    } 
608+ 
609+     /// Construct PyArray from `ndarray::ArrayBase`. 
610+      /// 
611+      /// This method allocates memory in Python's heap via numpy api, and then copies all elements 
612+      /// of the array there. 
613+      /// 
614+      /// # Example 
615+      /// ``` 
616+      /// # #[macro_use] extern crate ndarray; 
617+      /// use numpy::PyArray; 
618+      /// let gil = pyo3::Python::acquire_gil(); 
619+      /// let pyarray = PyArray::from_array(gil.python(), &array![[1, 2], [3, 4]]); 
620+      /// assert_eq!(pyarray.readonly().as_array(), array![[1, 2], [3, 4]]); 
621+      /// ``` 
622+      pub  fn  from_array < ' py ,  S > ( py :  Python < ' py > ,  arr :  & ArrayBase < S ,  D > )  -> & ' py  Self 
623+     where 
624+         S :  Data < Elem  = T > , 
625+     { 
626+         ToPyArray :: to_pyarray ( arr,  py) 
627+     } 
628+ 
629+     /// Get the immutable view of the internal data of `PyArray`, as 
630+      /// [`ndarray::ArrayView`](https://docs.rs/ndarray/latest/ndarray/type.ArrayView.html). 
631+      /// 
632+      /// # Safety 
633+      /// If the internal array is not readonly and can be mutated from Python code, 
634+      /// holding the `ArrayView` might cause undefined behavior. 
635+      pub  unsafe  fn  as_array ( & self )  -> ArrayView < ' _ ,  T ,  D >  { 
636+         ArrayView :: from_shape_ptr ( self . ndarray_shape ( ) ,  self . data ( ) ) 
637+     } 
638+ 
639+     /// Returns the internal array as `ArrayViewMut`. See also [`as_array`](#method.as_array). 
640+      /// 
641+      /// # Safety 
642+      /// If another reference to the internal data exists(e.g., `&[T]` or `ArrayView`), 
643+      /// it might cause undefined behavior. 
644+      pub  unsafe  fn  as_array_mut ( & self )  -> ArrayViewMut < ' _ ,  T ,  D >  { 
645+         ArrayViewMut :: from_shape_ptr ( self . ndarray_shape ( ) ,  self . data ( ) ) 
646+     } 
647+ 
648+     /// Get a copy of `PyArray` as 
649+      /// [`ndarray::Array`](https://docs.rs/ndarray/latest/ndarray/type.Array.html). 
650+      /// 
651+      /// # Example 
652+      /// ``` 
653+      /// # #[macro_use] extern crate ndarray; 
654+      /// use numpy::PyArray; 
655+      /// let gil = pyo3::Python::acquire_gil(); 
656+      /// let py_array = PyArray::arange(gil.python(), 0, 4, 1).reshape([2, 2]).unwrap(); 
657+      /// assert_eq!( 
658+      ///     py_array.to_owned_array(), 
659+      ///     array![[0, 1], [2, 3]] 
660+      /// ) 
661+      /// ``` 
662+      pub  fn  to_owned_array ( & self )  -> Array < T ,  D >  { 
663+         unsafe  {  self . as_array ( )  } . to_owned ( ) 
664+     } 
675665} 
676666
677- impl < T :  TypeNum >  PyArray < T ,  Ix1 >  { 
667+ impl < T :  Element >  PyArray < T ,  Ix1 >  { 
678668    /// Construct one-dimension PyArray from slice. 
679669     /// 
680670     /// # Example 
@@ -808,7 +798,7 @@ impl<T: TypeNum> PyArray<T, Ix1> {
808798    } 
809799} 
810800
811- impl < T :  TypeNum >  PyArray < T ,  Ix2 >  { 
801+ impl < T :  Element >  PyArray < T ,  Ix2 >  { 
812802    /// Construct a two-dimension PyArray from `Vec<Vec<T>>`. 
813803     /// 
814804     /// This function checks all dimension of inner vec, and if there's any vec 
@@ -824,10 +814,7 @@ impl<T: TypeNum> PyArray<T, Ix2> {
824814     /// assert_eq!(pyarray.readonly().as_array(), array![[1, 2, 3], [1, 2, 3]]); 
825815     /// assert!(PyArray::from_vec2(gil.python(), &[vec![1], vec![2, 3]]).is_err()); 
826816     /// ``` 
827-      pub  fn  from_vec2 < ' py > ( py :  Python < ' py > ,  v :  & [ Vec < T > ] )  -> Result < & ' py  Self ,  FromVecError > 
828-     where 
829-         T :  Clone , 
830-     { 
817+      pub  fn  from_vec2 < ' py > ( py :  Python < ' py > ,  v :  & [ Vec < T > ] )  -> Result < & ' py  Self ,  FromVecError >  { 
831818        let  last_len = v. last ( ) . map_or ( 0 ,  |v| v. len ( ) ) ; 
832819        if  v. iter ( ) . any ( |v| v. len ( )  != last_len)  { 
833820            return  Err ( FromVecError :: new ( v. len ( ) ,  last_len) ) ; 
@@ -837,15 +824,15 @@ impl<T: TypeNum> PyArray<T, Ix2> {
837824        unsafe  { 
838825            for  ( y,  vy)  in  v. iter ( ) . enumerate ( )  { 
839826                for  ( x,  vyx)  in  vy. iter ( ) . enumerate ( )  { 
840-                     * array. uget_mut ( [ y,  x] )  = * vyx; 
827+                     * array. uget_mut ( [ y,  x] )  = vyx. clone ( ) ; 
841828                } 
842829            } 
843830        } 
844831        Ok ( array) 
845832    } 
846833} 
847834
848- impl < T :  TypeNum >  PyArray < T ,  Ix3 >  { 
835+ impl < T :  Element >  PyArray < T ,  Ix3 >  { 
849836    /// Construct a three-dimension PyArray from `Vec<Vec<Vec<T>>>`. 
850837     /// 
851838     /// This function checks all dimension of inner vec, and if there's any vec 
@@ -864,10 +851,7 @@ impl<T: TypeNum> PyArray<T, Ix3> {
864851     /// ); 
865852     /// assert!(PyArray::from_vec3(gil.python(), &[vec![vec![1], vec![]]]).is_err()); 
866853     /// ``` 
867-      pub  fn  from_vec3 < ' py > ( py :  Python < ' py > ,  v :  & [ Vec < Vec < T > > ] )  -> Result < & ' py  Self ,  FromVecError > 
868-     where 
869-         T :  Clone , 
870-     { 
854+      pub  fn  from_vec3 < ' py > ( py :  Python < ' py > ,  v :  & [ Vec < Vec < T > > ] )  -> Result < & ' py  Self ,  FromVecError >  { 
871855        let  len2 = v. last ( ) . map_or ( 0 ,  |v| v. len ( ) ) ; 
872856        if  v. iter ( ) . any ( |v| v. len ( )  != len2)  { 
873857            return  Err ( FromVecError :: new ( v. len ( ) ,  len2) ) ; 
@@ -882,7 +866,7 @@ impl<T: TypeNum> PyArray<T, Ix3> {
882866            for  ( z,  vz)  in  v. iter ( ) . enumerate ( )  { 
883867                for  ( y,  vzy)  in  vz. iter ( ) . enumerate ( )  { 
884868                    for  ( x,  vzyx)  in  vzy. iter ( ) . enumerate ( )  { 
885-                         * array. uget_mut ( [ z,  y,  x] )  = * vzyx; 
869+                         * array. uget_mut ( [ z,  y,  x] )  = vzyx. clone ( ) ; 
886870                    } 
887871                } 
888872            } 
@@ -891,12 +875,7 @@ impl<T: TypeNum> PyArray<T, Ix3> {
891875    } 
892876} 
893877
894- impl < T :  TypeNum ,  D >  PyArray < T ,  D >  { 
895-     /// Returns the scalar type of the array. 
896-      pub  fn  data_type ( & self )  -> NpyDataType  { 
897-         NpyDataType :: from_i32 ( self . typenum ( ) ) 
898-     } 
899- 
878+ impl < T :  Element ,  D >  PyArray < T ,  D >  { 
900879    /// Copies self into `other`, performing a data-type conversion if necessary. 
901880     /// # Example 
902881     /// ``` 
@@ -907,7 +886,7 @@ impl<T: TypeNum, D> PyArray<T, D> {
907886     /// assert!(pyarray_f.copy_to(pyarray_i).is_ok()); 
908887     /// assert_eq!(pyarray_i.readonly().as_slice().unwrap(), &[2, 3, 4]); 
909888     /// ``` 
910-      pub  fn  copy_to < U :  TypeNum > ( & self ,  other :  & PyArray < U ,  D > )  -> PyResult < ( ) >  { 
889+      pub  fn  copy_to < U :  Element > ( & self ,  other :  & PyArray < U ,  D > )  -> PyResult < ( ) >  { 
911890        let  self_ptr = self . as_array_ptr ( ) ; 
912891        let  other_ptr = other. as_array_ptr ( ) ; 
913892        let  result = unsafe  {  PY_ARRAY_API . PyArray_CopyInto ( other_ptr,  self_ptr)  } ; 
@@ -926,9 +905,9 @@ impl<T: TypeNum, D> PyArray<T, D> {
926905     /// let pyarray_f = PyArray::arange(gil.python(), 2.0, 5.0, 1.0); 
927906     /// let pyarray_i = pyarray_f.cast::<i32>(false).unwrap(); 
928907     /// assert_eq!(pyarray_i.readonly().as_slice().unwrap(), &[2, 3, 4]); 
929-      pub  fn  cast < ' py ,  U :  TypeNum > ( & ' py  self ,  is_fortran :  bool )  -> PyResult < & ' py  PyArray < U ,  D > >  { 
908+      pub  fn  cast < ' py ,  U :  Element > ( & ' py  self ,  is_fortran :  bool )  -> PyResult < & ' py  PyArray < U ,  D > >  { 
930909        let  ptr = unsafe  { 
931-             let  descr = PY_ARRAY_API . PyArray_DescrFromType ( U :: typenum_default ( ) ) ; 
910+             let  descr = PY_ARRAY_API . PyArray_DescrFromType ( U :: ffi_dtype ( )   as   i32 ) ; 
932911            PY_ARRAY_API . PyArray_CastToType ( 
933912                self . as_array_ptr ( ) , 
934913                descr, 
@@ -995,7 +974,7 @@ impl<T: TypeNum, D> PyArray<T, D> {
995974    } 
996975} 
997976
998- impl < T :  TypeNum  + AsPrimitive < f64 > >  PyArray < T ,  Ix1 >  { 
977+ impl < T :  Element  + AsPrimitive < f64 > >  PyArray < T ,  Ix1 >  { 
999978    /// Return evenly spaced values within a given interval. 
1000979     /// Same as [numpy.arange](https://numpy.org/doc/stable/reference/generated/numpy.arange.html). 
1001980     /// 
@@ -1015,7 +994,7 @@ impl<T: TypeNum + AsPrimitive<f64>> PyArray<T, Ix1> {
1015994                start. as_ ( ) , 
1016995                stop. as_ ( ) , 
1017996                step. as_ ( ) , 
1018-                 T :: typenum_default ( ) , 
997+                 T :: ffi_dtype ( )   as   i32 , 
1019998            ) ; 
1020999            Self :: from_owned_ptr ( py,  ptr) 
10211000        } 
0 commit comments