Skip to content

Commit 755bdb1

Browse files
committed
Refactor IntoPyErr
Implement From<ErrorKind> for PyErr and now IntoPyErr is only for passing message to Python
1 parent 430e022 commit 755bdb1

File tree

5 files changed

+41
-19
lines changed

5 files changed

+41
-19
lines changed

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ extern crate numpy;
9595
extern crate pyo3;
9696

9797
use ndarray::{ArrayD, ArrayViewD, ArrayViewMutD};
98-
use numpy::{IntoPyResult, PyArrayDyn, ToPyArray};
98+
use numpy::{PyArrayDyn, ToPyArray};
9999
use pyo3::prelude::{pymodinit, PyModule, PyResult, Python};
100100

101101
#[pymodinit]
@@ -118,21 +118,22 @@ fn rust_ext(_py: Python, m: &PyModule) -> PyResult<()> {
118118
x: &PyArrayDyn<f64>,
119119
y: &PyArrayDyn<f64>,
120120
) -> PyResult<PyArrayDyn<f64>> {
121-
let x = x.as_array().into_pyresult("x must be f64 array")?;
122-
let y = y.as_array().into_pyresult("y must be f64 array")?;
121+
let x = x.as_array()?;
122+
let y = y.as_array()?;
123123
Ok(axpy(a, x, y).to_pyarray(py).to_owned(py))
124124
}
125125

126126
// wrapper of `mult`
127127
#[pyfn(m, "mult")]
128128
fn mult_py(_py: Python, a: f64, x: &PyArrayDyn<f64>) -> PyResult<()> {
129-
let x = x.as_array_mut().into_pyresult("x must be f64 array")?;
129+
let x = x.as_array_mut()?;
130130
mult(a, x);
131131
Ok(())
132132
}
133133

134134
Ok(())
135135
}
136+
136137
```
137138

138139
Contribution

example/extensions/src/lib.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ extern crate numpy;
33
extern crate pyo3;
44

55
use ndarray::{ArrayD, ArrayViewD, ArrayViewMutD};
6-
use numpy::{IntoPyResult, PyArrayDyn, ToPyArray};
6+
use numpy::{PyArrayDyn, ToPyArray};
77
use pyo3::prelude::{pymodinit, PyModule, PyResult, Python};
88

99
#[pymodinit]
@@ -26,15 +26,15 @@ fn rust_ext(_py: Python, m: &PyModule) -> PyResult<()> {
2626
x: &PyArrayDyn<f64>,
2727
y: &PyArrayDyn<f64>,
2828
) -> PyResult<PyArrayDyn<f64>> {
29-
let x = x.as_array().into_pyresult("x must be f64 array")?;
30-
let y = y.as_array().into_pyresult("y must be f64 array")?;
29+
let x = x.as_array()?;
30+
let y = y.as_array()?;
3131
Ok(axpy(a, x, y).to_pyarray(py).to_owned(py))
3232
}
3333

3434
// wrapper of `mult`
3535
#[pyfn(m, "mult")]
3636
fn mult_py(_py: Python, a: f64, x: &PyArrayDyn<f64>) -> PyResult<()> {
37-
let x = x.as_array_mut().into_pyresult("x must be f64 array")?;
37+
let x = x.as_array_mut()?;
3838
mult(a, x);
3939
Ok(())
4040
}

src/array.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use std::os::raw::c_int;
1010
use std::ptr;
1111

1212
use convert::{NpyIndex, ToNpyDims};
13-
use error::{ErrorKind, IntoPyErr};
13+
use error::{ErrorKind, IntoPyResult};
1414
use types::{NpyDataType, TypeNum};
1515

1616
/// A safe, static-typed interface for
@@ -130,7 +130,7 @@ impl<'a, T: TypeNum, D: Dimension> FromPyObject<'a> for &'a PyArray<T, D> {
130130
array
131131
.type_check()
132132
.map(|_| array)
133-
.map_err(|err| err.into_pyerr("FromPyObject::extract typecheck failed"))
133+
.into_pyresult_with(|| "FromPyObject::extract typecheck failed")
134134
}
135135
}
136136

src/error.rs

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,27 @@ use std::error;
77
use std::fmt;
88
use types::{NpyDataType, TypeNum};
99

10-
pub trait IntoPyErr {
11-
fn into_pyerr(self, msg: &str) -> PyErr;
10+
pub trait IntoPyErr: Into<PyErr> {
11+
fn into_pyerr(self) -> PyErr;
12+
fn into_pyerr_with<D: fmt::Display>(self, impl FnOnce() -> D) -> PyErr;
1213
}
1314

1415
pub trait IntoPyResult {
1516
type ValueType;
16-
fn into_pyresult(self, msg: &str) -> PyResult<Self::ValueType>;
17+
fn into_pyresult(self) -> PyResult<Self::ValueType>;
18+
fn into_pyresult_with<D: fmt::Display>(self, impl FnOnce() -> D) -> PyResult<Self::ValueType>;
1719
}
1820

1921
impl<T, E: IntoPyErr> IntoPyResult for Result<T, E> {
2022
type ValueType = T;
21-
fn into_pyresult(self, msg: &str) -> PyResult<T> {
22-
self.map_err(|e| e.into_pyerr(msg))
23+
fn into_pyresult(self) -> PyResult<Self::ValueType> {
24+
self.map_err(|e| e.into())
25+
}
26+
fn into_pyresult_with<D: fmt::Display>(
27+
self,
28+
msg: impl FnOnce() -> D,
29+
) -> PyResult<Self::ValueType> {
30+
self.map_err(|e| e.into_pyerr_with(msg))
2331
}
2432
}
2533

@@ -117,11 +125,24 @@ impl fmt::Display for ErrorKind {
117125

118126
impl error::Error for ErrorKind {}
119127

128+
impl From<ErrorKind> for PyErr {
129+
fn from(err: ErrorKind) -> PyErr {
130+
match err {
131+
ErrorKind::PyToRust { .. } | ErrorKind::FromVec { .. } | ErrorKind::PyToPy(_) => {
132+
PyErr::new::<exc::TypeError, _>(format!("{}", err))
133+
}
134+
}
135+
}
136+
}
137+
120138
impl IntoPyErr for ErrorKind {
121-
fn into_pyerr(self, msg: &str) -> PyErr {
139+
fn into_pyerr(self) -> PyErr {
140+
Into::into(self)
141+
}
142+
fn into_pyerr_with<D: fmt::Display>(self, msg: impl FnOnce() -> D) -> PyErr {
122143
match self {
123144
ErrorKind::PyToRust { .. } | ErrorKind::FromVec { .. } | ErrorKind::PyToPy(_) => {
124-
PyErr::new::<exc::TypeError, _>(format!("{}, msg: {}", self, msg))
145+
PyErr::new::<exc::TypeError, _>(format!("{} msg: {}", self, msg()))
125146
}
126147
}
127148
}

src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ pub use array::{
5151
PyArrayDyn,
5252
};
5353
pub use convert::{NpyIndex, ToNpyDims, ToPyArray};
54-
pub use error::{IntoPyErr, IntoPyResult, ArrayFormat, ErrorKind};
54+
pub use error::{ArrayFormat, ErrorKind, IntoPyErr, IntoPyResult};
55+
pub use ndarray::{Ix1, Ix2, Ix3, Ix4, Ix5, Ix6, IxDyn};
5556
pub use npyffi::{PY_ARRAY_API, PY_UFUNC_API};
5657
pub use types::{c32, c64, NpyDataType, TypeNum};
57-
pub use ndarray::{Ix1, Ix2, Ix3, Ix4, Ix5, Ix6, IxDyn};

0 commit comments

Comments
 (0)