Skip to content

Commit 0a7b10c

Browse files
committed
feat: add From conversions for standard library errors
1 parent eeb3214 commit 0a7b10c

2 files changed

Lines changed: 53 additions & 0 deletions

File tree

newsfragments/9999.added.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Added `From` conversions for `std::time::TryFromFloatSecsError`, `std::time::SystemTimeError`, `std::path::StripPrefixError`, `std::env::JoinPathsError`, `std::char::ParseCharError`, and `std::char::CharTryFromError` to map to Python's `ValueError`.

src/err/impls.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,12 @@ impl_to_pyerr!(std::num::TryFromIntError, exceptions::PyValueError);
182182
impl_to_pyerr!(std::str::ParseBoolError, exceptions::PyValueError);
183183
impl_to_pyerr!(std::ffi::NulError, exceptions::PyValueError);
184184
impl_to_pyerr!(std::net::AddrParseError, exceptions::PyValueError);
185+
impl_to_pyerr!(std::time::TryFromFloatSecsError, exceptions::PyValueError);
186+
impl_to_pyerr!(std::time::SystemTimeError, exceptions::PyValueError);
187+
impl_to_pyerr!(std::path::StripPrefixError, exceptions::PyValueError);
188+
impl_to_pyerr!(std::env::JoinPathsError, exceptions::PyValueError);
189+
impl_to_pyerr!(std::char::ParseCharError, exceptions::PyValueError);
190+
impl_to_pyerr!(std::char::CharTryFromError, exceptions::PyValueError);
185191

186192
#[cfg(test)]
187193
mod tests {
@@ -293,4 +299,50 @@ mod tests {
293299
.into();
294300
check_err(from_utf8_err);
295301
}
302+
303+
#[test]
304+
fn std_error_conversions() {
305+
Python::attach(|py| {
306+
let check_err = |err: PyErr, expected_msg: &str| {
307+
let py_err = err.into_bound_py_any(py).unwrap();
308+
assert!(py_err.is_instance_of::<crate::exceptions::PyValueError>());
309+
let msg = py_err.str().unwrap().to_string();
310+
assert_eq!(msg, expected_msg);
311+
};
312+
313+
// TryFromFloatSecsError
314+
let float_secs_err = std::time::Duration::try_from_secs_f32(-1.0).unwrap_err();
315+
let expected = float_secs_err.to_string();
316+
check_err(float_secs_err.into(), &expected);
317+
318+
// SystemTimeError
319+
let sys_time_err = std::time::SystemTime::now()
320+
.duration_since(std::time::SystemTime::now() + std::time::Duration::from_secs(1))
321+
.unwrap_err();
322+
let expected = sys_time_err.to_string();
323+
check_err(sys_time_err.into(), &expected);
324+
325+
// StripPrefixError
326+
let strip_prefix_err = std::path::Path::new("/a/b/c")
327+
.strip_prefix("/x/y/z")
328+
.unwrap_err();
329+
let expected = strip_prefix_err.to_string();
330+
check_err(strip_prefix_err.into(), &expected);
331+
332+
// JoinPathsError
333+
let join_paths_err = std::env::join_paths(["a:b", "a;b", "a\"b"].iter()).unwrap_err();
334+
let expected = join_paths_err.to_string();
335+
check_err(join_paths_err.into(), &expected);
336+
337+
// ParseCharError
338+
let parse_char_err = "abc".parse::<char>().unwrap_err();
339+
let expected = parse_char_err.to_string();
340+
check_err(parse_char_err.into(), &expected);
341+
342+
// CharTryFromError
343+
let char_try_from_err = char::try_from(0xD800_u32).unwrap_err();
344+
let expected = char_try_from_err.to_string();
345+
check_err(char_try_from_err.into(), &expected);
346+
});
347+
}
296348
}

0 commit comments

Comments
 (0)