PyTryFrom::try_from_mut_unchecked()

This commit is contained in:
ijl 2018-12-01 10:27:48 -05:00
parent d18ebea1c2
commit b8a6d67e31
2 changed files with 25 additions and 15 deletions

View file

@ -237,6 +237,11 @@ pub trait PyTryFrom: Sized {
/// Cast a PyObjectRef to a specific type of PyObject. The caller must
/// have already verified the reference is for this type.
unsafe fn try_from_unchecked(value: &PyObjectRef) -> &Self;
/// Cast a PyObjectRef to a specific type of PyObject. The caller must
/// have already verified the reference is for this type.
#[allow(clippy::mut_from_ref)]
unsafe fn try_from_mut_unchecked(value: &PyObjectRef) -> &mut Self;
}
// TryFrom implies TryInto
@ -287,12 +292,7 @@ where
fn try_from_mut(value: &PyObjectRef) -> Result<&mut T, PyDowncastError> {
unsafe {
if T::is_instance(value) {
let ptr = if T::OFFSET == 0 {
value as *const _ as *mut u8 as *mut T
} else {
(value.as_ptr() as *mut u8).offset(T::OFFSET) as *mut T
};
Ok(&mut *ptr)
Ok(PyTryFrom::try_from_mut_unchecked(value))
} else {
Err(PyDowncastError)
}
@ -302,12 +302,7 @@ where
fn try_from_mut_exact(value: &PyObjectRef) -> Result<&mut T, PyDowncastError> {
unsafe {
if T::is_exact_instance(value) {
let ptr = if T::OFFSET == 0 {
value as *const _ as *mut u8 as *mut T
} else {
(value.as_ptr() as *mut u8).offset(T::OFFSET) as *mut T
};
Ok(&mut *ptr)
Ok(PyTryFrom::try_from_mut_unchecked(value))
} else {
Err(PyDowncastError)
}
@ -323,6 +318,16 @@ where
};
&*ptr
}
#[inline]
unsafe fn try_from_mut_unchecked(value: &PyObjectRef) -> &mut T {
let ptr = if T::OFFSET == 0 {
value as *const _ as *mut u8 as *mut T
} else {
(value.as_ptr() as *mut u8).offset(T::OFFSET) as *mut T
};
&mut *ptr
}
}
/// This trait wraps a T: IntoPyObject into PyResult<T> while PyResult<T> remains PyResult<T>.

View file

@ -293,8 +293,7 @@ impl PyTryFrom for PySequence {
fn try_from_mut(value: &PyObjectRef) -> Result<&mut PySequence, PyDowncastError> {
unsafe {
if ffi::PySequence_Check(value.as_ptr()) != 0 {
let ptr = value as *const _ as *mut PySequence;
Ok(&mut *ptr)
Ok(<PySequence as PyTryFrom>::try_from_mut_unchecked(value))
} else {
Err(PyDowncastError)
}
@ -302,7 +301,7 @@ impl PyTryFrom for PySequence {
}
fn try_from_mut_exact(value: &PyObjectRef) -> Result<&mut PySequence, PyDowncastError> {
PySequence::try_from_mut(value)
<PySequence as PyTryFrom>::try_from_mut(value)
}
#[inline]
@ -310,6 +309,12 @@ impl PyTryFrom for PySequence {
let ptr = value as *const _ as *const PySequence;
&*ptr
}
#[inline]
unsafe fn try_from_mut_unchecked(value: &PyObjectRef) -> &mut PySequence {
let ptr = value as *const _ as *mut PySequence;
&mut *ptr
}
}
#[cfg(test)]