add std TryFrom impl for type conversion #73

This commit is contained in:
Nikolay Kim 2017-08-02 14:47:54 -07:00
parent e44365bec6
commit 44da09a0f4
7 changed files with 26 additions and 13 deletions

View File

@ -58,7 +58,7 @@ impl IntoPyObject for bool {
/// Converts a Python `bool` to a rust `bool`.
///
/// Fails with `TypeError` if the input is not a Python `bool`.
pyobject_extract!(py, obj to bool => {
pyobject_extract!(obj to bool => {
Ok(PyBool::try_from(obj)?.is_true())
});

View File

@ -48,7 +48,7 @@ impl IntoPyObject for f64 {
}
}
pyobject_extract!(py, obj to f64 => {
pyobject_extract!(obj to f64 => {
let v = unsafe { ffi::PyFloat_AsDouble(obj.as_ptr()) };
if v == -1.0 && PyErr::occurred(obj.py()) {
Err(PyErr::fetch(obj.py()))
@ -68,8 +68,8 @@ impl IntoPyObject for f32 {
}
}
pyobject_extract!(py, obj to f32 => {
Ok(try!(obj.extract::<f64>()) as f32)
pyobject_extract!(obj to f32 => {
Ok(obj.extract::<f64>()? as f32)
});

View File

@ -166,7 +166,7 @@ macro_rules! pyobject_nativetype(
);
macro_rules! pyobject_extract(
($py:ident, $obj:ident to $t:ty => $body: block) => {
($obj:ident to $t:ty => $body: block) => {
impl<'source> $crate::FromPyObject<'source> for $t
{
fn extract($obj: &'source $crate::PyObjectRef) -> $crate::PyResult<Self>
@ -177,6 +177,19 @@ macro_rules! pyobject_extract(
$body
}
}
impl<'source> $crate::std::convert::TryFrom<&'source $crate::PyObjectRef> for $t
{
type Error = $crate::PyErr;
fn try_from($obj: &$crate::PyObjectRef) -> Result<Self, $crate::PyErr>
{
#[allow(unused_imports)]
use $crate::ObjectProtocol;
$body
}
}
}
);

View File

@ -43,7 +43,7 @@ pyobject_nativetype!(PyLong, PyLong_Type, PyLong_Check);
impl PyInt {
/// Creates a new Python 2.7 `int` object.
///
/// Note: you might want to call `val.to_py_object(py)` instead
/// Note: you might want to call `val.to_object(py)` instead
/// to avoid truncation if the value does not fit into a `c_long`,
/// and to make your code compatible with Python 3.x.
pub fn new(_py: Python, val: c_long) -> Py<PyInt> {
@ -57,7 +57,7 @@ impl PyInt {
/// Warning: `PyInt::value()` is only supported for Python 2.7 `int` objects,
/// but not for `long` objects.
/// In almost all cases, you can avoid the distinction between these types
/// by simply calling `obj.extract::<i32>(py)`.
/// by simply calling `obj.extract::<i32>()`.
pub fn value(&self) -> c_long {
unsafe { ffi::PyInt_AS_LONG(self.0.as_ptr()) }
}
@ -79,7 +79,7 @@ macro_rules! int_fits_c_long(
}
}
}
pyobject_extract!(py, obj to $rust_type => {
pyobject_extract!(obj to $rust_type => {
let val = unsafe { ffi::PyLong_AsLong(obj.as_ptr()) };
if val == -1 && PyErr::occurred(obj.py()) {
return Err(PyErr::fetch(obj.py()));
@ -106,7 +106,7 @@ macro_rules! int_fits_larger_int(
(self as $larger_type).into_object(py)
}
}
pyobject_extract!(py, obj to $rust_type => {
pyobject_extract!(obj to $rust_type => {
let val = try!(obj.extract::<$larger_type>());
match cast::<$larger_type, $rust_type>(val) {
Some(v) => Ok(v),

View File

@ -43,7 +43,7 @@ macro_rules! int_fits_c_long(
}
}
}
pyobject_extract!(py, obj to $rust_type => {
pyobject_extract!(obj to $rust_type => {
let val = unsafe { ffi::PyLong_AsLong(obj.as_ptr()) };
if val == -1 && PyErr::occurred(obj.py()) {
return Err(PyErr::fetch(obj.py()));
@ -70,7 +70,7 @@ macro_rules! int_fits_larger_int(
(self as $larger_type).into_object(py)
}
}
pyobject_extract!(py, obj to $rust_type => {
pyobject_extract!(obj to $rust_type => {
let val = try!(obj.extract::<$larger_type>());
match cast::<$larger_type, $rust_type>(val) {
Some(v) => Ok(v),

View File

@ -65,7 +65,7 @@ impl<'source> ::FromPyObject<'source> for Cow<'source, str>
/// Allows extracting strings from Python objects.
/// Accepts Python `str` and `unicode` objects.
pyobject_extract!(py, obj to String => {
pyobject_extract!(obj to String => {
PyString::try_from(obj)?.to_string().map(Cow::into_owned)
});

View File

@ -237,7 +237,7 @@ impl IntoPyTuple for () {
/// Returns `Ok(NoArgs)` if the input is an empty Python tuple.
/// Otherwise, returns an error.
pyobject_extract!(py, obj to NoArgs => {
pyobject_extract!(obj to NoArgs => {
let t = PyTuple::try_from(obj)?;
if t.len() == 0 {
Ok(NoArgs)