diff --git a/newsfragments/6001.added.md b/newsfragments/6001.added.md new file mode 100644 index 00000000000..b30b97d7eaa --- /dev/null +++ b/newsfragments/6001.added.md @@ -0,0 +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`. diff --git a/src/err/impls.rs b/src/err/impls.rs index 86e36a4c136..57aec8f7b21 100644 --- a/src/err/impls.rs +++ b/src/err/impls.rs @@ -182,6 +182,12 @@ impl_to_pyerr!(std::num::TryFromIntError, exceptions::PyValueError); impl_to_pyerr!(std::str::ParseBoolError, exceptions::PyValueError); impl_to_pyerr!(std::ffi::NulError, exceptions::PyValueError); impl_to_pyerr!(std::net::AddrParseError, exceptions::PyValueError); +impl_to_pyerr!(std::time::TryFromFloatSecsError, exceptions::PyValueError); +impl_to_pyerr!(std::time::SystemTimeError, exceptions::PyValueError); +impl_to_pyerr!(std::path::StripPrefixError, exceptions::PyValueError); +impl_to_pyerr!(std::env::JoinPathsError, exceptions::PyValueError); +impl_to_pyerr!(std::char::ParseCharError, exceptions::PyValueError); +impl_to_pyerr!(std::char::CharTryFromError, exceptions::PyValueError); #[cfg(test)] mod tests { @@ -293,4 +299,50 @@ mod tests { .into(); check_err(from_utf8_err); } + + #[test] + fn std_error_conversions() { + Python::attach(|py| { + let check_err = |err: PyErr, expected_msg: &str| { + let py_err = err.into_bound_py_any(py).unwrap(); + assert!(py_err.is_instance_of::()); + let msg = py_err.str().unwrap().to_string(); + assert_eq!(msg, expected_msg); + }; + + // TryFromFloatSecsError + let float_secs_err = std::time::Duration::try_from_secs_f32(-1.0).unwrap_err(); + let expected = float_secs_err.to_string(); + check_err(float_secs_err.into(), &expected); + + // SystemTimeError + let sys_time_err = std::time::SystemTime::now() + .duration_since(std::time::SystemTime::now() + std::time::Duration::from_secs(1)) + .unwrap_err(); + let expected = sys_time_err.to_string(); + check_err(sys_time_err.into(), &expected); + + // StripPrefixError + let strip_prefix_err = std::path::Path::new("/a/b/c") + .strip_prefix("/x/y/z") + .unwrap_err(); + let expected = strip_prefix_err.to_string(); + check_err(strip_prefix_err.into(), &expected); + + // JoinPathsError + let join_paths_err = std::env::join_paths(["a:b", "a;b", "a\"b"].iter()).unwrap_err(); + let expected = join_paths_err.to_string(); + check_err(join_paths_err.into(), &expected); + + // ParseCharError + let parse_char_err = "abc".parse::().unwrap_err(); + let expected = parse_char_err.to_string(); + check_err(parse_char_err.into(), &expected); + + // CharTryFromError + let char_try_from_err = char::try_from(0xD800_u32).unwrap_err(); + let expected = char_try_from_err.to_string(); + check_err(char_try_from_err.into(), &expected); + }); + } }