Skip to content

Commit

Permalink
use Py2Borrowed to make PyBytesMethods slightly nicer
Browse files Browse the repository at this point in the history
  • Loading branch information
davidhewitt committed Dec 14, 2023
1 parent 98bf4b6 commit 41345ed
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 10 deletions.
2 changes: 1 addition & 1 deletion src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ impl<'a, 'py> Py2Borrowed<'a, 'py, PyAny> {
}
}

impl<'a, 'py, T> From<&'a Py2<'py, T>> for Py2Borrowed<'a, 'py, PyAny> {
impl<'a, 'py, T> From<&'a Py2<'py, T>> for Py2Borrowed<'a, 'py, T> {
/// Create borrow on a Py2
fn from(instance: &'a Py2<'py, T>) -> Self {
Self(
Expand Down
22 changes: 13 additions & 9 deletions src/types/bytes.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::instance::Py2;
use crate::instance::{Py2, Py2Borrowed};
use crate::{ffi, FromPyObject, IntoPy, Py, PyAny, PyResult, Python, ToPyObject};
use std::borrow::Cow;
use std::ops::Index;
Expand Down Expand Up @@ -89,9 +89,7 @@ impl PyBytes {
/// Gets the Python string as a byte slice.
#[inline]
pub fn as_bytes(&self) -> &[u8] {
let slice = Py2::borrowed_from_gil_ref(&self).as_bytes();
// SAFETY: &self guarantees the reference is alive long enough
unsafe { std::slice::from_raw_parts(slice.as_ptr(), slice.len()) }
Py2Borrowed::from_gil_ref(self).as_bytes()
}
}

Expand All @@ -109,6 +107,13 @@ pub(crate) trait PyBytesMethods<'py> {
impl<'py> PyBytesMethods<'py> for Py2<'py, PyBytes> {
#[inline]
fn as_bytes(&self) -> &[u8] {
Py2Borrowed::from(self).as_bytes()
}
}

impl<'a> Py2Borrowed<'a, '_, PyBytes> {
/// Gets the Python string as a byte slice.
fn as_bytes(self) -> &'a [u8] {
unsafe {
let buffer = ffi::PyBytes_AsString(self.as_ptr()) as *const u8;
let length = ffi::PyBytes_Size(self.as_ptr()) as usize;
Expand All @@ -122,11 +127,10 @@ impl Py<PyBytes> {
/// Gets the Python bytes as a byte slice. Because Python bytes are
/// immutable, the result may be used for as long as the reference to
/// `self` is held, including when the GIL is released.
pub fn as_bytes<'a>(&'a self, py: Python<'_>) -> &'a [u8] {
let slice = self.attach(py).as_bytes();
// SAFETY: it is safe to access the immutable slice as long as the
// reference to `self` is held.
unsafe { std::slice::from_raw_parts(slice.as_ptr(), slice.len()) }
pub fn as_bytes<'a>(&'a self, _py: Python<'_>) -> &'a [u8] {
// Safety: `Py2Borrowed` has the same layout as `Py`
let borrowed: Py2Borrowed<'a, '_, PyBytes> = unsafe { std::mem::transmute_copy(self) };
borrowed.as_bytes()
}
}

Expand Down

0 comments on commit 41345ed

Please sign in to comment.