Convert some std error types to PyErr (#22)
* Convert some std error types to PyErr * Add ToPyErr trait
This commit is contained in:
parent
a584ce12e5
commit
e12e98a7c1
57
src/err.rs
57
src/err.rs
|
@ -1,6 +1,8 @@
|
|||
use std;
|
||||
use std::io;
|
||||
use std::ffi::CString;
|
||||
use std::os::raw::c_char;
|
||||
use std::error::Error;
|
||||
use libc;
|
||||
|
||||
use ffi;
|
||||
|
@ -369,6 +371,61 @@ impl std::convert::From<PyErr> for std::io::Error {
|
|||
}
|
||||
}
|
||||
|
||||
/// Converts into PyErr
|
||||
pub trait ToPyErr {
|
||||
fn to_pyerr(&self, Python) -> PyErr;
|
||||
}
|
||||
|
||||
macro_rules! impl_to_pyerr {
|
||||
($err: ty, $pyexc: ty) => {
|
||||
impl $crate::ToPyErr for $err {
|
||||
fn to_pyerr(&self, py: $crate::Python) -> PyErr {
|
||||
PyErr::new::<$pyexc, _>(py, self.description())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Create OSError from io::Error
|
||||
impl ToPyErr for io::Error {
|
||||
|
||||
fn to_pyerr(&self, py: Python) -> PyErr {
|
||||
let tp = match self.kind() {
|
||||
io::ErrorKind::BrokenPipe => py.get_type::<exc::BrokenPipeError>(),
|
||||
io::ErrorKind::ConnectionRefused => py.get_type::<exc::ConnectionRefusedError>(),
|
||||
io::ErrorKind::ConnectionAborted => py.get_type::<exc::ConnectionAbortedError>(),
|
||||
io::ErrorKind::ConnectionReset => py.get_type::<exc::ConnectionResetError>(),
|
||||
io::ErrorKind::Interrupted => py.get_type::<exc::InterruptedError>(),
|
||||
io::ErrorKind::NotFound => py.get_type::<exc::FileNotFoundError>(),
|
||||
io::ErrorKind::WouldBlock => py.get_type::<exc::BlockingIOError>(),
|
||||
io::ErrorKind::TimedOut => py.get_type::<exc::TimeoutError>(),
|
||||
_ => py.get_type::<exc::OSError>(),
|
||||
};
|
||||
|
||||
let errno = self.raw_os_error().unwrap_or(0);
|
||||
let errdesc = self.description();
|
||||
|
||||
PyErr::new_err(py, &tp, (errno, errdesc))
|
||||
}
|
||||
}
|
||||
|
||||
impl<W: Send + std::fmt::Debug> ToPyErr for std::io::IntoInnerError<W> {
|
||||
fn to_pyerr(&self, py: Python) -> PyErr {
|
||||
PyErr::new::<exc::OSError, _>(py, self.description())
|
||||
}
|
||||
}
|
||||
|
||||
impl_to_pyerr!(std::num::ParseIntError, exc::ValueError);
|
||||
impl_to_pyerr!(std::num::ParseFloatError, exc::ValueError);
|
||||
impl_to_pyerr!(std::string::ParseError, exc::ValueError);
|
||||
impl_to_pyerr!(std::str::ParseBoolError, exc::ValueError);
|
||||
impl_to_pyerr!(std::ffi::IntoStringError, exc::UnicodeDecodeError);
|
||||
impl_to_pyerr!(std::str::Utf8Error, exc::UnicodeDecodeError);
|
||||
impl_to_pyerr!(std::string::FromUtf8Error, exc::UnicodeDecodeError);
|
||||
impl_to_pyerr!(std::string::FromUtf16Error, exc::UnicodeDecodeError);
|
||||
impl_to_pyerr!(std::char::DecodeUtf16Error, exc::UnicodeDecodeError);
|
||||
impl_to_pyerr!(std::net::AddrParseError, exc::ValueError);
|
||||
|
||||
pub fn panic_after_error() -> ! {
|
||||
unsafe { ffi::PyErr_Print(); }
|
||||
panic!("Python API called failed");
|
||||
|
|
|
@ -70,7 +70,7 @@ pub use pointers::PyPtr;
|
|||
mod token;
|
||||
pub use token::{PyToken, PyObjectWithToken, ToInstancePtr, InstancePtr};
|
||||
|
||||
pub use err::{PyErr, PyResult, PyDowncastError};
|
||||
pub use err::{PyErr, PyResult, PyDowncastError, ToPyErr};
|
||||
pub use objects::*;
|
||||
pub use objectprotocol::ObjectProtocol;
|
||||
pub use python::{Python, ToPyPointer, IntoPyPointer, PyClone,
|
||||
|
|
Loading…
Reference in a new issue