@@ -26,7 +26,7 @@ use crate::cold;
26
26
use crate :: convert:: { ArrayExt , IntoPyArray , NpyIndex , ToNpyDims , ToPyArray } ;
27
27
use crate :: dtype:: { Element , PyArrayDescr } ;
28
28
use crate :: error:: {
29
- BorrowError , DimensionalityError , FromVecError , NotContiguousError , TypeError ,
29
+ BorrowError , DimensionalityError , FromVecError , IgnoreError , NotContiguousError , TypeError ,
30
30
DIMENSIONALITY_MISMATCH_ERR , MAX_DIMENSIONALITY_ERR ,
31
31
} ;
32
32
use 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> {
131
131
}
132
132
133
133
fn is_type_of ( ob : & PyAny ) -> bool {
134
- < & Self > :: extract ( ob) . is_ok ( )
134
+ Self :: extract :: < IgnoreError > ( ob) . is_ok ( )
135
135
}
136
136
}
137
137
@@ -145,30 +145,7 @@ impl<T, D> IntoPy<PyObject> for PyArray<T, D> {
145
145
146
146
impl < ' py , T : Element , D : Dimension > FromPyObject < ' py > for & ' py PyArray < T , D > {
147
147
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)
172
149
}
173
150
}
174
151
@@ -390,6 +367,36 @@ impl<T, D> PyArray<T, D> {
390
367
}
391
368
392
369
impl < 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
+
393
400
/// Same as [`shape`][Self::shape], but returns `D` insead of `&[usize]`.
394
401
#[ inline( always) ]
395
402
pub fn dims ( & self ) -> D {
0 commit comments