Skip to content

Commit

Permalink
Add BoundRef::ref_from_ptr_or_opt
Browse files Browse the repository at this point in the history
  • Loading branch information
LilyFoote committed Feb 22, 2024
1 parent c602d8d commit 4de8b1a
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 2 deletions.
5 changes: 3 additions & 2 deletions pyo3-macros-backend/src/pymethod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -572,11 +572,12 @@ pub fn impl_py_setter_def(
_slf: *mut _pyo3::ffi::PyObject,
_value: *mut _pyo3::ffi::PyObject,
) -> _pyo3::PyResult<::std::os::raw::c_int> {
let _value = _pyo3::Bound::from_borrowed_ptr_or_opt(py, _value)
use ::std::convert::Into;
let _value = _pyo3::impl_::pymethods::BoundRef::ref_from_ptr_or_opt(py, &_value)
.ok_or_else(|| {
_pyo3::exceptions::PyAttributeError::new_err("can't delete attribute")
})?;
let _val = _pyo3::FromPyObject::extract_bound(&_value)?;
let _val = _pyo3::FromPyObject::extract_bound(_value.into())?;
#( #holders )*
_pyo3::callback::convert(py, #setter_impl)
}
Expand Down
7 changes: 7 additions & 0 deletions src/impl_/pymethods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,13 @@ impl<'a, 'py> BoundRef<'a, 'py, PyAny> {
BoundRef(Bound::ref_from_ptr(py, ptr))
}

pub unsafe fn ref_from_ptr_or_opt(
py: Python<'py>,
ptr: &'a *mut ffi::PyObject,
) -> Option<Self> {
Bound::ref_from_ptr_or_opt(py, ptr).as_ref().map(BoundRef)
}

pub unsafe fn downcast_unchecked<T>(self) -> BoundRef<'a, 'py, T> {
BoundRef(self.0.downcast_unchecked::<T>())
}
Expand Down
12 changes: 12 additions & 0 deletions src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,18 @@ impl<'py> Bound<'py, PyAny> {
) -> &'a Self {
&*(ptr as *const *mut ffi::PyObject).cast::<Bound<'py, PyAny>>()
}

/// Variant of the above which returns `None` for null pointers.
///
/// # Safety
/// - `ptr` must be a valid pointer to a Python object for the lifetime `'a, or null.
#[inline]
pub(crate) unsafe fn ref_from_ptr_or_opt<'a>(
_py: Python<'py>,
ptr: &'a *mut ffi::PyObject,
) -> &'a Option<Self> {
&*(ptr as *const *mut ffi::PyObject).cast::<Option<Bound<'py, PyAny>>>()
}
}

impl<'py, T> Bound<'py, T>
Expand Down

0 comments on commit 4de8b1a

Please sign in to comment.