@@ -26,7 +26,7 @@ use crate::cold;
2626use crate :: convert:: { ArrayExt , IntoPyArray , NpyIndex , ToNpyDims , ToPyArray } ;
2727use crate :: dtype:: { Element , PyArrayDescr } ;
2828use crate :: error:: {
29- BorrowError , DimensionalityError , FromVecError , NotContiguousError , TypeError ,
29+ BorrowError , DimensionalityError , FromVecError , IgnoreError , NotContiguousError , TypeError ,
3030 DIMENSIONALITY_MISMATCH_ERR , MAX_DIMENSIONALITY_ERR ,
3131} ;
3232use crate :: npyffi:: { self , npy_intp, NPY_ORDER , PY_ARRAY_API } ;
@@ -131,7 +131,7 @@ unsafe impl<T: Element, D: Dimension> PyTypeInfo for PyArray<T, D> {
131131 }
132132
133133 fn is_type_of ( ob : & PyAny ) -> bool {
134- < & Self > :: extract ( ob) . is_ok ( )
134+ Self :: extract :: < IgnoreError > ( ob) . is_ok ( )
135135 }
136136}
137137
@@ -145,30 +145,7 @@ impl<T, D> IntoPy<PyObject> for PyArray<T, D> {
145145
146146impl < ' py , T : Element , D : Dimension > FromPyObject < ' py > for & ' py PyArray < T , D > {
147147 fn extract ( ob : & ' py PyAny ) -> PyResult < Self > {
148- // Check if the object is an array.
149- let array = unsafe {
150- if npyffi:: PyArray_Check ( ob. py ( ) , ob. as_ptr ( ) ) == 0 {
151- return Err ( PyDowncastError :: new ( ob, PyArray :: < T , D > :: NAME ) . into ( ) ) ;
152- }
153- & * ( ob as * const PyAny as * const PyArray < T , D > )
154- } ;
155-
156- // Check if the dimensionality matches `D`.
157- let src_ndim = array. ndim ( ) ;
158- if let Some ( dst_ndim) = D :: NDIM {
159- if src_ndim != dst_ndim {
160- return Err ( DimensionalityError :: new ( src_ndim, dst_ndim) . into ( ) ) ;
161- }
162- }
163-
164- // Check if the element type matches `T`.
165- let src_dtype = array. dtype ( ) ;
166- let dst_dtype = T :: get_dtype ( ob. py ( ) ) ;
167- if !src_dtype. is_equiv_to ( dst_dtype) {
168- return Err ( TypeError :: new ( src_dtype, dst_dtype) . into ( ) ) ;
169- }
170-
171- Ok ( array)
148+ PyArray :: extract ( ob)
172149 }
173150}
174151
@@ -390,6 +367,36 @@ impl<T, D> PyArray<T, D> {
390367}
391368
392369impl < T : Element , D : Dimension > PyArray < T , D > {
370+ fn extract < ' py , E > ( ob : & ' py PyAny ) -> Result < & ' py Self , E >
371+ where
372+ E : From < PyDowncastError < ' py > > + From < DimensionalityError > + From < TypeError < ' py > > ,
373+ {
374+ // Check if the object is an array.
375+ let array = unsafe {
376+ if npyffi:: PyArray_Check ( ob. py ( ) , ob. as_ptr ( ) ) == 0 {
377+ return Err ( PyDowncastError :: new ( ob, Self :: NAME ) . into ( ) ) ;
378+ }
379+ & * ( ob as * const PyAny as * const Self )
380+ } ;
381+
382+ // Check if the dimensionality matches `D`.
383+ let src_ndim = array. ndim ( ) ;
384+ if let Some ( dst_ndim) = D :: NDIM {
385+ if src_ndim != dst_ndim {
386+ return Err ( DimensionalityError :: new ( src_ndim, dst_ndim) . into ( ) ) ;
387+ }
388+ }
389+
390+ // Check if the element type matches `T`.
391+ let src_dtype = array. dtype ( ) ;
392+ let dst_dtype = T :: get_dtype ( ob. py ( ) ) ;
393+ if !src_dtype. is_equiv_to ( dst_dtype) {
394+ return Err ( TypeError :: new ( src_dtype, dst_dtype) . into ( ) ) ;
395+ }
396+
397+ Ok ( array)
398+ }
399+
393400 /// Same as [`shape`][Self::shape], but returns `D` insead of `&[usize]`.
394401 #[ inline( always) ]
395402 pub fn dims ( & self ) -> D {
0 commit comments