Skip to content

Commit 312f00a

Browse files
authored
Merge pull request #118 from kngwyu/err-fetch
Properly fetch errors in Python interpreter
2 parents 6aad7ae + 6d9572e commit 312f00a

File tree

4 files changed

+15
-63
lines changed

4 files changed

+15
-63
lines changed

src/array.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -813,7 +813,7 @@ impl<T: TypeNum> PyArray<T, Ix1> {
813813
)
814814
};
815815
if res.is_null() {
816-
Err(ErrorKind::dims_cast(self, dims))
816+
Err(ErrorKind::py(self.py()))
817817
} else {
818818
Ok(())
819819
}
@@ -936,7 +936,7 @@ impl<T: TypeNum, D> PyArray<T, D> {
936936
let other_ptr = other.as_array_ptr();
937937
let result = unsafe { PY_ARRAY_API.PyArray_CopyInto(other_ptr, self_ptr) };
938938
if result == -1 {
939-
Err(ErrorKind::dtype_cast(self, U::npy_data_type()))
939+
Err(ErrorKind::py(self.py()))
940940
} else {
941941
Ok(())
942942
}
@@ -965,7 +965,7 @@ impl<T: TypeNum, D> PyArray<T, D> {
965965
)
966966
};
967967
if ptr.is_null() {
968-
Err(ErrorKind::dtype_cast(self, U::npy_data_type()))
968+
Err(ErrorKind::py(self.py()))
969969
} else {
970970
Ok(unsafe { PyArray::<U, D>::from_owned_ptr(self.py(), ptr) })
971971
}
@@ -1018,7 +1018,7 @@ impl<T: TypeNum, D> PyArray<T, D> {
10181018
)
10191019
};
10201020
if ptr.is_null() {
1021-
Err(ErrorKind::dims_cast(self, dims))
1021+
Err(ErrorKind::py(self.py()))
10221022
} else {
10231023
Ok(unsafe { PyArray::<T, D2>::from_owned_ptr(self.py(), ptr) })
10241024
}

src/error.rs

Lines changed: 10 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use crate::array::PyArray;
44
use crate::convert::ToNpyDims;
55
use crate::types::{NpyDataType, TypeNum};
6-
use pyo3::{exceptions as exc, PyErr, PyResult};
6+
use pyo3::{exceptions as exc, PyErr, PyResult, Python};
77
use std::error;
88
use std::fmt;
99

@@ -34,42 +34,6 @@ impl<T, E: IntoPyErr> IntoPyResult for Result<T, E> {
3434
}
3535
}
3636

37-
/// Represents a shape and dtype of numpy array.
38-
///
39-
/// Only for error formatting.
40-
#[derive(Debug)]
41-
pub struct ArrayShape {
42-
pub dims: Box<[usize]>,
43-
pub dtype: NpyDataType,
44-
}
45-
46-
impl ArrayShape {
47-
fn boxed_dims(dims: &[usize]) -> Box<[usize]> {
48-
dims.into_iter()
49-
.map(|&x| x)
50-
.collect::<Vec<_>>()
51-
.into_boxed_slice()
52-
}
53-
fn from_array<T: TypeNum, D>(array: &PyArray<T, D>) -> Self {
54-
ArrayShape {
55-
dims: Self::boxed_dims(array.shape()),
56-
dtype: T::npy_data_type(),
57-
}
58-
}
59-
fn from_dims<T: TypeNum, D: ToNpyDims>(dims: D) -> Self {
60-
ArrayShape {
61-
dims: Self::boxed_dims(dims.slice()),
62-
dtype: T::npy_data_type(),
63-
}
64-
}
65-
}
66-
67-
impl fmt::Display for ArrayShape {
68-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
69-
write!(f, "dims={:?}, dtype={:?}", self.dims, self.dtype)
70-
}
71-
}
72-
7337
/// Represents a dimension and dtype of numpy array.
7438
///
7539
/// Only for error formatting.
@@ -96,8 +60,8 @@ pub enum ErrorKind {
9660
PyToRust { from: ArrayDim, to: ArrayDim },
9761
/// Error for casting rust's `Vec` into numpy array.
9862
FromVec { dim1: usize, dim2: usize },
99-
/// Error in numpy -> numpy data conversion
100-
PyToPy(Box<(ArrayShape, ArrayShape)>),
63+
/// Error occured in Python iterpreter
64+
Python(PyErr),
10165
/// The array need to be contiguous to finish the opretion
10266
NotContiguous,
10367
}
@@ -120,18 +84,8 @@ impl ErrorKind {
12084
},
12185
}
12286
}
123-
pub(crate) fn dtype_cast<T: TypeNum, D>(from: &PyArray<T, D>, to: NpyDataType) -> Self {
124-
let from = ArrayShape::from_array(from);
125-
let to = ArrayShape {
126-
dims: from.dims.clone(),
127-
dtype: to,
128-
};
129-
ErrorKind::PyToPy(Box::new((from, to)))
130-
}
131-
pub(crate) fn dims_cast<T: TypeNum, D>(from: &PyArray<T, D>, to_dim: impl ToNpyDims) -> Self {
132-
let from = ArrayShape::from_array(from);
133-
let to = ArrayShape::from_dims::<T, _>(to_dim);
134-
ErrorKind::PyToPy(Box::new((from, to)))
87+
pub(crate) fn py(py: Python<'_>) -> Self {
88+
ErrorKind::Python(PyErr::fetch(py))
13589
}
13690
}
13791

@@ -146,11 +100,7 @@ impl fmt::Display for ErrorKind {
146100
"Cast failed: Vec To PyArray:\n expect all dim {} but {} was found",
147101
dim1, dim2
148102
),
149-
ErrorKind::PyToPy(e) => write!(
150-
f,
151-
"Cast failed: from=ndarray({}), to=ndarray(dtype={})",
152-
e.0, e.1,
153-
),
103+
ErrorKind::Python(e) => write!(f, "Python error: {:?}", e),
154104
ErrorKind::NotContiguous => write!(f, "This array is not contiguous!"),
155105
}
156106
}
@@ -160,7 +110,10 @@ impl error::Error for ErrorKind {}
160110

161111
impl From<ErrorKind> for PyErr {
162112
fn from(err: ErrorKind) -> PyErr {
163-
PyErr::new::<exc::TypeError, _>(format!("{}", err))
113+
match err {
114+
ErrorKind::Python(e) => e,
115+
_ => PyErr::new::<exc::TypeError, _>(format!("{}", err)),
116+
}
164117
}
165118
}
166119

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ pub use crate::array::{
4848
PyArrayDyn,
4949
};
5050
pub use crate::convert::{IntoPyArray, NpyIndex, ToNpyDims, ToPyArray};
51-
pub use crate::error::{ArrayShape, ErrorKind, IntoPyErr, IntoPyResult};
51+
pub use crate::error::{ErrorKind, IntoPyErr, IntoPyResult};
5252
pub use crate::npyffi::{PY_ARRAY_API, PY_UFUNC_API};
5353
pub use crate::types::{c32, c64, NpyDataType, TypeNum};
5454
pub use ndarray::{Ix1, Ix2, Ix3, Ix4, Ix5, Ix6, IxDyn};

tests/to_py.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ macro_rules! small_array_test {
6868
small_array_test!(i8 u8 i16 u16 i32 u32 i64 u64 usize);
6969

7070
#[test]
71-
#[ignore]
7271
fn usize_dtype() {
7372
let gil = pyo3::Python::acquire_gil();
7473
let py = gil.python();

0 commit comments

Comments
 (0)