Add `Py::drop_ref` method (#3871)
* add Py::drop_ref method * add changelog entry * fix ffi import * integrate review feedback * Add a test * Fix some build errors * Fix some more build errors
This commit is contained in:
parent
61bc02d927
commit
885883bf68
|
@ -0,0 +1 @@
|
|||
Add `Py::drop_ref` to explicitly drop a `Py`` and immediately decrease the Python reference count if the GIL is already held.
|
|
@ -822,6 +822,10 @@ impl<T> IntoPy<PyObject> for Borrowed<'_, '_, T> {
|
|||
/// Otherwise, the reference count will be decreased the next time the GIL is
|
||||
/// reacquired.
|
||||
///
|
||||
/// If you happen to be already holding the GIL, [`Py::drop_ref`] will decrease
|
||||
/// the Python reference count immediately and will execute slightly faster than
|
||||
/// relying on implicit [`Drop`]s.
|
||||
///
|
||||
/// # A note on `Send` and `Sync`
|
||||
///
|
||||
/// Accessing this object is threadsafe, since any access to its API requires a [`Python<'py>`](crate::Python) token.
|
||||
|
@ -1228,6 +1232,35 @@ impl<T> Py<T> {
|
|||
unsafe { Py::from_borrowed_ptr(py, self.0.as_ptr()) }
|
||||
}
|
||||
|
||||
/// Drops `self` and immediately decreases its reference count.
|
||||
///
|
||||
/// This method is a micro-optimisation over [`Drop`] if you happen to be holding the GIL
|
||||
/// already.
|
||||
///
|
||||
/// Note that if you are using [`Bound`], you do not need to use [`Self::drop_ref`] since
|
||||
/// [`Bound`] guarantees that the GIL is held.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use pyo3::prelude::*;
|
||||
/// use pyo3::types::PyDict;
|
||||
///
|
||||
/// # fn main() {
|
||||
/// Python::with_gil(|py| {
|
||||
/// let object: Py<PyDict> = PyDict::new_bound(py).unbind();
|
||||
///
|
||||
/// // some usage of object
|
||||
///
|
||||
/// object.drop_ref(py);
|
||||
/// });
|
||||
/// # }
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn drop_ref(self, py: Python<'_>) {
|
||||
let _ = self.into_bound(py);
|
||||
}
|
||||
|
||||
/// Returns whether the object is considered to be None.
|
||||
///
|
||||
/// This is equivalent to the Python expression `self is None`.
|
||||
|
@ -2142,6 +2175,23 @@ a = A()
|
|||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn explicit_drop_ref() {
|
||||
Python::with_gil(|py| {
|
||||
let object: Py<PyDict> = PyDict::new_bound(py).unbind();
|
||||
let object2 = object.clone_ref(py);
|
||||
|
||||
assert_eq!(object.as_ptr(), object2.as_ptr());
|
||||
assert_eq!(object.get_refcnt(py), 2);
|
||||
|
||||
object.drop_ref(py);
|
||||
|
||||
assert_eq!(object2.get_refcnt(py), 1);
|
||||
|
||||
object2.drop_ref(py);
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(feature = "macros")]
|
||||
mod using_macros {
|
||||
use crate::PyCell;
|
||||
|
|
Loading…
Reference in New Issue