Skip to content

Commit ab57251

Browse files
authored
Merge pull request #185 from yingmanwumen/refactor_pyerr
refactor: using pyerr instead of panic
2 parents d8c643b + 901a4c2 commit ab57251

File tree

9 files changed

+205
-172
lines changed

9 files changed

+205
-172
lines changed

ulist/src/base.rs

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use crate::boolean::BooleanList;
22
use crate::index::IndexList;
33
use pyo3::exceptions::PyIndexError;
4+
use pyo3::exceptions::PyRuntimeError;
5+
use pyo3::exceptions::PyValueError;
46
use pyo3::PyResult;
57
use std::cell::Ref;
68
use std::cell::RefMut;
@@ -25,9 +27,13 @@ where
2527

2628
fn _new(vec: Vec<T>, hset: HashSet<usize>) -> Self;
2729

28-
fn _check_len_eq(&self, other: &Self) {
30+
fn _check_len_eq(&self, other: &Self) -> PyResult<()> {
2931
if self.size() != other.size() {
30-
panic!("The sizes of `self` and `other` should be equal!");
32+
Err(PyRuntimeError::new_err(
33+
"The sizes of `self` and `other` should be equal!",
34+
))
35+
} else {
36+
Ok(())
3137
}
3238
}
3339

@@ -103,13 +109,15 @@ where
103109
BooleanList::new(vec, HashSet::new())
104110
}
105111

106-
fn filter(&self, condition: &BooleanList) -> Self {
112+
fn filter(&self, condition: &BooleanList) -> PyResult<Self> {
107113
if self.size() != condition.size() {
108-
panic!("The sizes of `self` and `other` should be equal!");
109-
}
110-
111-
if condition.count_na() > 0 {
112-
panic!("Parameter `condition` should not contain missing values!");
114+
return Err(PyRuntimeError::new_err(
115+
"The sizes of `self` and `other` should be equal!",
116+
));
117+
} else if condition.count_na() > 0 {
118+
return Err(PyValueError::new_err(
119+
"Parameter `condition` should not contain missing values!",
120+
));
113121
}
114122

115123
let n = self.size();
@@ -132,7 +140,7 @@ where
132140
}
133141
vec.shrink_to_fit();
134142
hset.shrink_to_fit();
135-
List::_new(vec, hset)
143+
Ok(List::_new(vec, hset))
136144
}
137145

138146
fn get(&self, index: usize) -> PyResult<Option<T>> {
@@ -148,11 +156,11 @@ where
148156
}
149157
}
150158

151-
fn get_by_indexes(&self, indexes: &IndexList) -> Self {
159+
fn get_by_indexes(&self, indexes: &IndexList) -> PyResult<Self> {
152160
// TODO: Put this kind of check
153161
// where there is unsafe block.
154162
if indexes.back() >= self.size() {
155-
panic!("Index out of range!")
163+
return Err(PyIndexError::new_err("Index out of range!"));
156164
}
157165
// TODO: use get_unchecked instead.
158166
let mut vec: Vec<T> = Vec::new();
@@ -165,7 +173,7 @@ where
165173
}
166174
i += 1;
167175
}
168-
List::_new(vec, hset)
176+
Ok(List::_new(vec, hset))
169177
}
170178

171179
fn has_na(&self) -> bool {
@@ -249,9 +257,9 @@ where
249257
self.na_indexes_mut().clear();
250258
}
251259

252-
fn set(&self, index: usize, elem: Option<T>) {
260+
fn set(&self, index: usize, elem: Option<T>) -> PyResult<()> {
253261
if index >= self.size() {
254-
panic!("Index out of range!");
262+
return Err(PyIndexError::new_err("Index out of range!"));
255263
}
256264
let mut vec = self.values_mut();
257265
// TODO: Use get_unchecked_mut instead.
@@ -268,6 +276,7 @@ where
268276
vec[index] = self.na_value();
269277
self.na_indexes_mut().insert(index);
270278
}
279+
Ok(())
271280
}
272281

273282
fn repeat(elem: T, size: usize) -> Self {

ulist/src/boolean.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ impl BooleanList {
4444
List::all_equal(self, other)
4545
}
4646

47-
pub fn and_(&self, other: &Self) -> Self {
47+
pub fn and_(&self, other: &Self) -> PyResult<Self> {
4848
_logical_operate(&self, &other, |x, y| x && y)
4949
}
5050

@@ -97,15 +97,15 @@ impl BooleanList {
9797
List::equal_scala(self, elem)
9898
}
9999

100-
pub fn filter(&self, condition: &BooleanList) -> Self {
100+
pub fn filter(&self, condition: &BooleanList) -> PyResult<Self> {
101101
List::filter(self, condition)
102102
}
103103

104104
pub fn get(&self, index: usize) -> PyResult<Option<bool>> {
105105
List::get(self, index)
106106
}
107107

108-
pub fn get_by_indexes(&self, indexes: &IndexList) -> Self {
108+
pub fn get_by_indexes(&self, indexes: &IndexList) -> PyResult<Self> {
109109
List::get_by_indexes(self, indexes)
110110
}
111111

@@ -120,7 +120,7 @@ impl BooleanList {
120120
List::not_equal_scala(self, elem)
121121
}
122122

123-
pub fn or_(&self, other: &Self) -> Self {
123+
pub fn or_(&self, other: &Self) -> PyResult<Self> {
124124
_logical_operate(&self, &other, |x, y| x || y)
125125
}
126126

@@ -137,7 +137,7 @@ impl BooleanList {
137137
List::replace(self, old, new)
138138
}
139139

140-
pub fn set(&self, index: usize, elem: Option<bool>) {
140+
pub fn set(&self, index: usize, elem: Option<bool>) -> PyResult<()> {
141141
List::set(self, index, elem)
142142
}
143143

@@ -212,15 +212,15 @@ fn _logical_operate(
212212
this: &BooleanList,
213213
other: &BooleanList,
214214
func: impl Fn(bool, bool) -> bool,
215-
) -> BooleanList {
216-
this._check_len_eq(other);
215+
) -> PyResult<BooleanList> {
216+
this._check_len_eq(other)?;
217217
let vec = this
218218
.values()
219219
.iter()
220220
.zip(other.values().iter())
221221
.map(|(&x, &y)| func(x, y))
222222
.collect();
223-
BooleanList::new(vec, HashSet::new())
223+
Ok(BooleanList::new(vec, HashSet::new()))
224224
}
225225

226226
impl AsFloatList32 for BooleanList {

ulist/src/control_flow.rs

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,18 @@ use crate::boolean::BooleanList;
33
use crate::floatings::FloatList64;
44
use crate::integers::IntegerList64;
55
use crate::string::StringList;
6+
use pyo3::exceptions::PyRuntimeError;
7+
use pyo3::exceptions::PyValueError;
68
use pyo3::prelude::*;
79
use pyo3::Py;
810
use std::collections::HashSet;
911

10-
fn select<T, U>(py: Python, conditions: &Vec<Py<BooleanList>>, choices: &Vec<T>, default: T) -> U
12+
fn select<T, U>(
13+
py: Python,
14+
conditions: &Vec<Py<BooleanList>>,
15+
choices: &Vec<T>,
16+
default: T,
17+
) -> PyResult<U>
1118
where
1219
T: PartialEq + Clone,
1320
U: List<T>,
@@ -16,10 +23,13 @@ where
1623
let n = cond[0].size();
1724
for c in cond.iter() {
1825
if c.size() != n {
19-
panic!("BooleanList sizes in conditions should be equal!");
20-
}
21-
if c.count_na() > 0 {
22-
panic!("Parameter `condition` should not contain missing values!");
26+
return Err(PyRuntimeError::new_err(
27+
"BooleanList sizes in conditions should be equal!",
28+
));
29+
} else if c.count_na() > 0 {
30+
return Err(PyValueError::new_err(
31+
"Parameter `condition` should not contain missing values!",
32+
));
2333
}
2434
}
2535

@@ -33,7 +43,7 @@ where
3343
}
3444
}
3545
}
36-
U::_new(vec, HashSet::new())
46+
Ok(U::_new(vec, HashSet::new()))
3747
}
3848

3949
#[pyfunction]
@@ -42,7 +52,7 @@ pub fn select_bool(
4252
conditions: Vec<Py<BooleanList>>,
4353
choices: Vec<bool>,
4454
default: bool,
45-
) -> BooleanList {
55+
) -> PyResult<BooleanList> {
4656
select::<bool, BooleanList>(py, &conditions, &choices, default)
4757
}
4858

@@ -52,7 +62,7 @@ pub fn select_float(
5262
conditions: Vec<Py<BooleanList>>,
5363
choices: Vec<f64>,
5464
default: f64,
55-
) -> FloatList64 {
65+
) -> PyResult<FloatList64> {
5666
select::<f64, FloatList64>(py, &conditions, &choices, default)
5767
}
5868

@@ -62,7 +72,7 @@ pub fn select_int(
6272
conditions: Vec<Py<BooleanList>>,
6373
choices: Vec<i64>,
6474
default: i64,
65-
) -> IntegerList64 {
75+
) -> PyResult<IntegerList64> {
6676
select::<i64, IntegerList64>(py, &conditions, &choices, default)
6777
}
6878

@@ -72,6 +82,6 @@ pub fn select_string(
7282
conditions: Vec<Py<BooleanList>>,
7383
choices: Vec<String>,
7484
default: String,
75-
) -> StringList {
85+
) -> PyResult<StringList> {
7686
select::<String, StringList>(py, &conditions, &choices, default)
7787
}

0 commit comments

Comments
 (0)