From f3ddd023c92bb2089e9716e8b37ed86af5004554 Mon Sep 17 00:00:00 2001 From: Icxolu <10486322+Icxolu@users.noreply.github.com> Date: Wed, 14 Feb 2024 23:10:59 +0100 Subject: [PATCH] convert `PyBuffer` to `Bound` API (#3836) --- pytests/src/buf_and_str.rs | 4 ++-- src/buffer.rs | 26 +++++++++++++++++++------- tests/test_buffer.rs | 12 ++++++------ tests/test_buffer_protocol.rs | 2 +- 4 files changed, 28 insertions(+), 16 deletions(-) diff --git a/pytests/src/buf_and_str.rs b/pytests/src/buf_and_str.rs index 196126f7..23db9f06 100644 --- a/pytests/src/buf_and_str.rs +++ b/pytests/src/buf_and_str.rs @@ -35,8 +35,8 @@ impl BytesExtractor { } #[staticmethod] - pub fn from_buffer(buf: &PyAny) -> PyResult { - let buf = PyBuffer::::get(buf)?; + pub fn from_buffer(buf: &Bound<'_, PyAny>) -> PyResult { + let buf = PyBuffer::::get_bound(buf)?; Ok(buf.item_count()) } } diff --git a/src/buffer.rs b/src/buffer.rs index 2e9afbca..84b08289 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -18,8 +18,8 @@ // DEALINGS IN THE SOFTWARE. //! `PyBuffer` implementation -use crate::instance::Bound; use crate::{err, exceptions::PyBufferError, ffi, FromPyObject, PyAny, PyResult, Python}; +use crate::{Bound, PyNativeType}; use std::marker::PhantomData; use std::os::raw; use std::pin::Pin; @@ -184,13 +184,25 @@ pub unsafe trait Element: Copy { impl<'py, T: Element> FromPyObject<'py> for PyBuffer { fn extract_bound(obj: &Bound<'_, PyAny>) -> PyResult> { - Self::get(obj.as_gil_ref()) + Self::get_bound(obj) } } impl PyBuffer { - /// Gets the underlying buffer from the specified python object. + /// Deprecated form of [`PyBuffer::get_bound`] + #[cfg_attr( + not(feature = "gil-refs"), + deprecated( + since = "0.21.0", + note = "`PyBuffer::get` will be replaced by `PyBuffer::get_bound` in a future PyO3 version" + ) + )] pub fn get(obj: &PyAny) -> PyResult> { + Self::get_bound(&obj.as_borrowed()) + } + + /// Gets the underlying buffer from the specified python object. + pub fn get_bound(obj: &Bound<'_, PyAny>) -> PyResult> { // TODO: use nightly API Box::new_uninit() once stable let mut buf = Box::new(mem::MaybeUninit::uninit()); let buf: Box = { @@ -696,7 +708,7 @@ mod tests { fn test_debug() { Python::with_gil(|py| { let bytes = py.eval_bound("b'abcde'", None, None).unwrap(); - let buffer: PyBuffer = PyBuffer::get(bytes.as_gil_ref()).unwrap(); + let buffer: PyBuffer = PyBuffer::get_bound(&bytes).unwrap(); let expected = format!( concat!( "PyBuffer {{ buf: {:?}, obj: {:?}, ", @@ -859,7 +871,7 @@ mod tests { fn test_bytes_buffer() { Python::with_gil(|py| { let bytes = py.eval_bound("b'abcde'", None, None).unwrap(); - let buffer = PyBuffer::get(bytes.as_gil_ref()).unwrap(); + let buffer = PyBuffer::get_bound(&bytes).unwrap(); assert_eq!(buffer.dimensions(), 1); assert_eq!(buffer.item_count(), 5); assert_eq!(buffer.format().to_str().unwrap(), "B"); @@ -895,7 +907,7 @@ mod tests { .unwrap() .call_method("array", ("f", (1.0, 1.5, 2.0, 2.5)), None) .unwrap(); - let buffer = PyBuffer::get(array.as_gil_ref()).unwrap(); + let buffer = PyBuffer::get_bound(&array).unwrap(); assert_eq!(buffer.dimensions(), 1); assert_eq!(buffer.item_count(), 4); assert_eq!(buffer.format().to_str().unwrap(), "f"); @@ -925,7 +937,7 @@ mod tests { assert_eq!(buffer.to_vec(py).unwrap(), [10.0, 11.0, 12.0, 13.0]); // F-contiguous fns - let buffer = PyBuffer::get(array.as_gil_ref()).unwrap(); + let buffer = PyBuffer::get_bound(&array).unwrap(); let slice = buffer.as_fortran_slice(py).unwrap(); assert_eq!(slice.len(), 4); assert_eq!(slice[1].get(), 11.0); diff --git a/tests/test_buffer.rs b/tests/test_buffer.rs index de8638ba..72f94b3b 100644 --- a/tests/test_buffer.rs +++ b/tests/test_buffer.rs @@ -96,11 +96,11 @@ fn test_get_buffer_errors() { ) .unwrap(); - assert!(PyBuffer::::get(instance.as_ref(py)).is_ok()); + assert!(PyBuffer::::get_bound(instance.bind(py).as_any()).is_ok()); instance.borrow_mut(py).error = Some(TestGetBufferError::NullShape); assert_eq!( - PyBuffer::::get(instance.as_ref(py)) + PyBuffer::::get_bound(instance.bind(py).as_any()) .unwrap_err() .to_string(), "BufferError: shape is null" @@ -108,7 +108,7 @@ fn test_get_buffer_errors() { instance.borrow_mut(py).error = Some(TestGetBufferError::NullStrides); assert_eq!( - PyBuffer::::get(instance.as_ref(py)) + PyBuffer::::get_bound(instance.bind(py).as_any()) .unwrap_err() .to_string(), "BufferError: strides is null" @@ -116,7 +116,7 @@ fn test_get_buffer_errors() { instance.borrow_mut(py).error = Some(TestGetBufferError::IncorrectItemSize); assert_eq!( - PyBuffer::::get(instance.as_ref(py)) + PyBuffer::::get_bound(instance.bind(py).as_any()) .unwrap_err() .to_string(), "BufferError: buffer contents are not compatible with u32" @@ -124,7 +124,7 @@ fn test_get_buffer_errors() { instance.borrow_mut(py).error = Some(TestGetBufferError::IncorrectFormat); assert_eq!( - PyBuffer::::get(instance.as_ref(py)) + PyBuffer::::get_bound(instance.bind(py).as_any()) .unwrap_err() .to_string(), "BufferError: buffer contents are not compatible with u32" @@ -132,7 +132,7 @@ fn test_get_buffer_errors() { instance.borrow_mut(py).error = Some(TestGetBufferError::IncorrectAlignment); assert_eq!( - PyBuffer::::get(instance.as_ref(py)) + PyBuffer::::get_bound(instance.bind(py).as_any()) .unwrap_err() .to_string(), "BufferError: buffer contents are insufficiently aligned for u32" diff --git a/tests/test_buffer_protocol.rs b/tests/test_buffer_protocol.rs index 0a3a1758..85ff6a40 100644 --- a/tests/test_buffer_protocol.rs +++ b/tests/test_buffer_protocol.rs @@ -77,7 +77,7 @@ fn test_buffer_referenced() { } .into_py(py); - let buf = PyBuffer::::get(instance.as_ref(py)).unwrap(); + let buf = PyBuffer::::get_bound(instance.bind(py)).unwrap(); assert_eq!(buf.to_vec(py).unwrap(), input); drop(instance); buf