From 6caefd151ee53b177229a6547722789b3925e367 Mon Sep 17 00:00:00 2001 From: Bas Schoenmaeckers <7943856+bschoenmaeckers@users.noreply.github.com> Date: Wed, 31 Jul 2024 09:42:07 +0200 Subject: [PATCH] Add back `PyBytes::new` (#4387) --- guide/src/conversions/traits.md | 2 +- pytests/src/buf_and_str.rs | 2 +- src/conversions/anyhow.rs | 2 +- src/conversions/eyre.rs | 2 +- src/conversions/num_bigint.rs | 2 +- src/conversions/std/slice.rs | 4 +-- src/pybacked.rs | 22 ++++++------- src/tests/hygiene/pymethods.rs | 2 +- src/types/bytes.rs | 55 ++++++++++++++++++++++++++------- tests/test_bytes.rs | 4 +-- 10 files changed, 64 insertions(+), 33 deletions(-) diff --git a/guide/src/conversions/traits.md b/guide/src/conversions/traits.md index c622bae58d2..344834f4a7c 100644 --- a/guide/src/conversions/traits.md +++ b/guide/src/conversions/traits.md @@ -388,7 +388,7 @@ enum RustyEnum<'py> { # } # # { -# let thing = PyBytes::new_bound(py, b"text"); +# let thing = PyBytes::new(py, b"text"); # let rust_thing: RustyEnum<'_> = thing.extract()?; # # assert_eq!( diff --git a/pytests/src/buf_and_str.rs b/pytests/src/buf_and_str.rs index 879d76af883..4a7add32bc2 100644 --- a/pytests/src/buf_and_str.rs +++ b/pytests/src/buf_and_str.rs @@ -43,7 +43,7 @@ impl BytesExtractor { #[pyfunction] fn return_memoryview(py: Python<'_>) -> PyResult> { - let bytes = PyBytes::new_bound(py, b"hello world"); + let bytes = PyBytes::new(py, b"hello world"); PyMemoryView::from_bound(&bytes) } diff --git a/src/conversions/anyhow.rs b/src/conversions/anyhow.rs index d6880ac4e96..0b2bf2bacfa 100644 --- a/src/conversions/anyhow.rs +++ b/src/conversions/anyhow.rs @@ -76,7 +76,7 @@ //! let res = Python::with_gil(|py| { //! let zlib = PyModule::import_bound(py, "zlib")?; //! let decompress = zlib.getattr("decompress")?; -//! let bytes = PyBytes::new_bound(py, bytes); +//! let bytes = PyBytes::new(py, bytes); //! let value = decompress.call1((bytes,))?; //! value.extract::>() //! })?; diff --git a/src/conversions/eyre.rs b/src/conversions/eyre.rs index 2d8b623fa58..9a876c3f1ef 100644 --- a/src/conversions/eyre.rs +++ b/src/conversions/eyre.rs @@ -75,7 +75,7 @@ //! let res = Python::with_gil(|py| { //! let zlib = PyModule::import_bound(py, "zlib")?; //! let decompress = zlib.getattr("decompress")?; -//! let bytes = PyBytes::new_bound(py, bytes); +//! let bytes = PyBytes::new(py, bytes); //! let value = decompress.call1((bytes,))?; //! value.extract::>() //! })?; diff --git a/src/conversions/num_bigint.rs b/src/conversions/num_bigint.rs index 99b5962622d..708c51bca62 100644 --- a/src/conversions/num_bigint.rs +++ b/src/conversions/num_bigint.rs @@ -112,7 +112,7 @@ macro_rules! bigint_conversion { #[cfg(Py_LIMITED_API)] fn to_object(&self, py: Python<'_>) -> PyObject { let bytes = $to_bytes(self); - let bytes_obj = PyBytes::new_bound(py, &bytes); + let bytes_obj = PyBytes::new(py, &bytes); let kwargs = if $is_signed { let kwargs = crate::types::PyDict::new_bound(py); kwargs.set_item(crate::intern!(py, "signed"), true).unwrap(); diff --git a/src/conversions/std/slice.rs b/src/conversions/std/slice.rs index 34b3e61eaf1..e2353a5d320 100644 --- a/src/conversions/std/slice.rs +++ b/src/conversions/std/slice.rs @@ -9,7 +9,7 @@ use crate::{ impl<'a> IntoPy for &'a [u8] { fn into_py(self, py: Python<'_>) -> PyObject { - PyBytes::new_bound(py, self).unbind().into() + PyBytes::new(py, self).unbind().into() } #[cfg(feature = "experimental-inspect")] @@ -52,7 +52,7 @@ impl<'a> crate::conversion::FromPyObjectBound<'a, '_> for Cow<'a, [u8]> { impl ToPyObject for Cow<'_, [u8]> { fn to_object(&self, py: Python<'_>) -> Py { - PyBytes::new_bound(py, self.as_ref()).into() + PyBytes::new(py, self.as_ref()).into() } } diff --git a/src/pybacked.rs b/src/pybacked.rs index f6a0f99fe9a..1d93042f039 100644 --- a/src/pybacked.rs +++ b/src/pybacked.rs @@ -207,7 +207,7 @@ impl ToPyObject for PyBackedBytes { fn to_object(&self, py: Python<'_>) -> Py { match &self.storage { PyBackedBytesStorage::Python(bytes) => bytes.to_object(py), - PyBackedBytesStorage::Rust(bytes) => PyBytes::new_bound(py, bytes).into_any().unbind(), + PyBackedBytesStorage::Rust(bytes) => PyBytes::new(py, bytes).into_any().unbind(), } } } @@ -216,7 +216,7 @@ impl IntoPy> for PyBackedBytes { fn into_py(self, py: Python<'_>) -> Py { match self.storage { PyBackedBytesStorage::Python(bytes) => bytes.into_any(), - PyBackedBytesStorage::Rust(bytes) => PyBytes::new_bound(py, &bytes).into_any().unbind(), + PyBackedBytesStorage::Rust(bytes) => PyBytes::new(py, &bytes).into_any().unbind(), } } } @@ -355,7 +355,7 @@ mod test { #[test] fn py_backed_bytes_empty() { Python::with_gil(|py| { - let b = PyBytes::new_bound(py, b""); + let b = PyBytes::new(py, b""); let py_backed_bytes = b.extract::().unwrap(); assert_eq!(&*py_backed_bytes, b""); }); @@ -364,7 +364,7 @@ mod test { #[test] fn py_backed_bytes() { Python::with_gil(|py| { - let b = PyBytes::new_bound(py, b"abcde"); + let b = PyBytes::new(py, b"abcde"); let py_backed_bytes = b.extract::().unwrap(); assert_eq!(&*py_backed_bytes, b"abcde"); }); @@ -373,7 +373,7 @@ mod test { #[test] fn py_backed_bytes_from_bytes() { Python::with_gil(|py| { - let b = PyBytes::new_bound(py, b"abcde"); + let b = PyBytes::new(py, b"abcde"); let py_backed_bytes = PyBackedBytes::from(b); assert_eq!(&*py_backed_bytes, b"abcde"); }); @@ -391,7 +391,7 @@ mod test { #[test] fn py_backed_bytes_into_py() { Python::with_gil(|py| { - let orig_bytes = PyBytes::new_bound(py, b"abcde"); + let orig_bytes = PyBytes::new(py, b"abcde"); let py_backed_bytes = PyBackedBytes::from(orig_bytes.clone()); assert!(py_backed_bytes.to_object(py).is(&orig_bytes)); assert!(py_backed_bytes.into_py(py).is(&orig_bytes)); @@ -495,7 +495,7 @@ mod test { #[test] fn test_backed_bytes_from_bytes_clone() { Python::with_gil(|py| { - let b1: PyBackedBytes = PyBytes::new_bound(py, b"abcde").into(); + let b1: PyBackedBytes = PyBytes::new(py, b"abcde").into(); let b2 = b1.clone(); assert_eq!(b1, b2); @@ -520,13 +520,13 @@ mod test { #[test] fn test_backed_bytes_eq() { Python::with_gil(|py| { - let b1: PyBackedBytes = PyBytes::new_bound(py, b"abcde").into(); + let b1: PyBackedBytes = PyBytes::new(py, b"abcde").into(); let b2: PyBackedBytes = PyByteArray::new_bound(py, b"abcde").into(); assert_eq!(b1, b"abcde"); assert_eq!(b1, b2); - let b3: PyBackedBytes = PyBytes::new_bound(py, b"hello").into(); + let b3: PyBackedBytes = PyBytes::new(py, b"hello").into(); assert_eq!(b"hello", b3); assert_ne!(b1, b3); }); @@ -541,7 +541,7 @@ mod test { hasher.finish() }; - let b1: PyBackedBytes = PyBytes::new_bound(py, b"abcde").into(); + let b1: PyBackedBytes = PyBytes::new(py, b"abcde").into(); let h1 = { let mut hasher = DefaultHasher::new(); b1.hash(&mut hasher); @@ -566,7 +566,7 @@ mod test { let mut a = vec![b"a", b"c", b"d", b"b", b"f", b"g", b"e"]; let mut b = a .iter() - .map(|&b| PyBytes::new_bound(py, b).into()) + .map(|&b| PyBytes::new(py, b).into()) .collect::>(); a.sort(); diff --git a/src/tests/hygiene/pymethods.rs b/src/tests/hygiene/pymethods.rs index 5abfc856ea2..af167db21c6 100644 --- a/src/tests/hygiene/pymethods.rs +++ b/src/tests/hygiene/pymethods.rs @@ -21,7 +21,7 @@ impl Dummy { } fn __bytes__<'py>(&self, py: crate::Python<'py>) -> crate::Bound<'py, crate::types::PyBytes> { - crate::types::PyBytes::new_bound(py, &[0]) + crate::types::PyBytes::new(py, &[0]) } fn __format__(&self, format_spec: ::std::string::String) -> ::std::string::String { diff --git a/src/types/bytes.rs b/src/types/bytes.rs index 0a8b4860d25..876cf156ab8 100644 --- a/src/types/bytes.rs +++ b/src/types/bytes.rs @@ -30,12 +30,12 @@ use std::str; /// use pyo3::types::PyBytes; /// /// # Python::with_gil(|py| { -/// let py_bytes = PyBytes::new_bound(py, b"foo".as_slice()); +/// let py_bytes = PyBytes::new(py, b"foo".as_slice()); /// // via PartialEq<[u8]> /// assert_eq!(py_bytes, b"foo".as_slice()); /// /// // via Python equality -/// let other = PyBytes::new_bound(py, b"foo".as_slice()); +/// let other = PyBytes::new(py, b"foo".as_slice()); /// assert!(py_bytes.as_any().eq(other).unwrap()); /// /// // Note that `eq` will convert it's argument to Python using `ToPyObject`, @@ -54,7 +54,7 @@ impl PyBytes { /// The bytestring is initialized by copying the data from the `&[u8]`. /// /// Panics if out of memory. - pub fn new_bound<'p>(py: Python<'p>, s: &[u8]) -> Bound<'p, PyBytes> { + pub fn new<'p>(py: Python<'p>, s: &[u8]) -> Bound<'p, PyBytes> { let ptr = s.as_ptr().cast(); let len = s.len() as ffi::Py_ssize_t; unsafe { @@ -64,6 +64,13 @@ impl PyBytes { } } + /// Deprecated name for [`PyBytes::new`]. + #[deprecated(since = "0.23.0", note = "renamed to `PyBytes::new`")] + #[inline] + pub fn new_bound<'p>(py: Python<'p>, s: &[u8]) -> Bound<'p, PyBytes> { + Self::new(py, s) + } + /// Creates a new Python `bytes` object with an `init` closure to write its contents. /// Before calling `init` the bytes' contents are zero-initialised. /// * If Python raises a MemoryError on the allocation, `new_with` will return @@ -78,7 +85,7 @@ impl PyBytes { /// /// # fn main() -> PyResult<()> { /// Python::with_gil(|py| -> PyResult<()> { - /// let py_bytes = PyBytes::new_bound_with(py, 10, |bytes: &mut [u8]| { + /// let py_bytes = PyBytes::new_with(py, 10, |bytes: &mut [u8]| { /// bytes.copy_from_slice(b"Hello Rust"); /// Ok(()) /// })?; @@ -88,7 +95,7 @@ impl PyBytes { /// }) /// # } /// ``` - pub fn new_bound_with(py: Python<'_>, len: usize, init: F) -> PyResult> + pub fn new_with(py: Python<'_>, len: usize, init: F) -> PyResult> where F: FnOnce(&mut [u8]) -> PyResult<()>, { @@ -106,6 +113,16 @@ impl PyBytes { } } + /// Deprecated name for [`PyBytes::new_with`]. + #[deprecated(since = "0.23.0", note = "renamed to `PyBytes::new_with`")] + #[inline] + pub fn new_bound_with(py: Python<'_>, len: usize, init: F) -> PyResult> + where + F: FnOnce(&mut [u8]) -> PyResult<()>, + { + Self::new_with(py, len, init) + } + /// Creates a new Python byte string object from a raw pointer and length. /// /// Panics if out of memory. @@ -116,11 +133,25 @@ impl PyBytes { /// leading pointer of a slice of length `len`. [As with /// `std::slice::from_raw_parts`, this is /// unsafe](https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html#safety). - pub unsafe fn bound_from_ptr(py: Python<'_>, ptr: *const u8, len: usize) -> Bound<'_, PyBytes> { + pub unsafe fn from_ptr(py: Python<'_>, ptr: *const u8, len: usize) -> Bound<'_, PyBytes> { ffi::PyBytes_FromStringAndSize(ptr.cast(), len as isize) .assume_owned(py) .downcast_into_unchecked() } + + /// Deprecated name for [`PyBytes::from_ptr`]. + /// + /// # Safety + /// + /// This function dereferences the raw pointer `ptr` as the + /// leading pointer of a slice of length `len`. [As with + /// `std::slice::from_raw_parts`, this is + /// unsafe](https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html#safety). + #[deprecated(since = "0.23.0", note = "renamed to `PyBytes::from_ptr`")] + #[inline] + pub unsafe fn bound_from_ptr(py: Python<'_>, ptr: *const u8, len: usize) -> Bound<'_, PyBytes> { + Self::from_ptr(py, ptr, len) + } } /// Implementation of functionality for [`PyBytes`]. @@ -279,7 +310,7 @@ mod tests { #[test] fn test_bytes_index() { Python::with_gil(|py| { - let bytes = PyBytes::new_bound(py, b"Hello World"); + let bytes = PyBytes::new(py, b"Hello World"); assert_eq!(bytes[1], b'e'); }); } @@ -287,7 +318,7 @@ mod tests { #[test] fn test_bound_bytes_index() { Python::with_gil(|py| { - let bytes = PyBytes::new_bound(py, b"Hello World"); + let bytes = PyBytes::new(py, b"Hello World"); assert_eq!(bytes[1], b'e'); let bytes = &bytes; @@ -298,7 +329,7 @@ mod tests { #[test] fn test_bytes_new_with() -> super::PyResult<()> { Python::with_gil(|py| -> super::PyResult<()> { - let py_bytes = PyBytes::new_bound_with(py, 10, |b: &mut [u8]| { + let py_bytes = PyBytes::new_with(py, 10, |b: &mut [u8]| { b.copy_from_slice(b"Hello Rust"); Ok(()) })?; @@ -311,7 +342,7 @@ mod tests { #[test] fn test_bytes_new_with_zero_initialised() -> super::PyResult<()> { Python::with_gil(|py| -> super::PyResult<()> { - let py_bytes = PyBytes::new_bound_with(py, 10, |_b: &mut [u8]| Ok(()))?; + let py_bytes = PyBytes::new_with(py, 10, |_b: &mut [u8]| Ok(()))?; let bytes: &[u8] = py_bytes.extract()?; assert_eq!(bytes, &[0; 10]); Ok(()) @@ -322,7 +353,7 @@ mod tests { fn test_bytes_new_with_error() { use crate::exceptions::PyValueError; Python::with_gil(|py| { - let py_bytes_result = PyBytes::new_bound_with(py, 10, |_b: &mut [u8]| { + let py_bytes_result = PyBytes::new_with(py, 10, |_b: &mut [u8]| { Err(PyValueError::new_err("Hello Crustaceans!")) }); assert!(py_bytes_result.is_err()); @@ -337,7 +368,7 @@ mod tests { fn test_comparisons() { Python::with_gil(|py| { let b = b"hello, world".as_slice(); - let py_bytes = PyBytes::new_bound(py, b); + let py_bytes = PyBytes::new(py, b); assert_eq!(py_bytes, b"hello, world".as_slice()); diff --git a/tests/test_bytes.rs b/tests/test_bytes.rs index 26686a2def3..4e58cdc08e0 100644 --- a/tests/test_bytes.rs +++ b/tests/test_bytes.rs @@ -21,7 +21,7 @@ fn test_pybytes_bytes_conversion() { #[pyfunction] fn bytes_vec_conversion(py: Python<'_>, bytes: Vec) -> Bound<'_, PyBytes> { - PyBytes::new_bound(py, bytes.as_slice()) + PyBytes::new(py, bytes.as_slice()) } #[test] @@ -43,7 +43,7 @@ fn test_bytearray_vec_conversion() { #[test] fn test_py_as_bytes() { let pyobj: pyo3::Py = - Python::with_gil(|py| pyo3::types::PyBytes::new_bound(py, b"abc").unbind()); + Python::with_gil(|py| pyo3::types::PyBytes::new(py, b"abc").unbind()); let data = Python::with_gil(|py| pyobj.as_bytes(py));