refactor: use `ptr_from_ref` and ptr `.cast()` (#4240)

* refactor: use `ptr_from_ref` and ptr `.cast()`

* fix unused imports
This commit is contained in:
David Hewitt 2024-06-07 23:47:27 +01:00 committed by GitHub
parent b8fb367582
commit 9c67057745
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 68 additions and 92 deletions

View File

@ -114,10 +114,7 @@ extern "C" {
#[cfg(not(any(Py_3_8, PyPy)))] #[cfg(not(any(Py_3_8, PyPy)))]
#[inline] #[inline]
pub unsafe fn PyIter_Check(o: *mut PyObject) -> c_int { pub unsafe fn PyIter_Check(o: *mut PyObject) -> c_int {
crate::PyObject_HasAttrString( crate::PyObject_HasAttrString(crate::Py_TYPE(o).cast(), "__next__\0".as_ptr().cast())
crate::Py_TYPE(o).cast(),
"__next__\0".as_ptr() as *const c_char,
)
} }
extern "C" { extern "C" {

View File

@ -61,7 +61,7 @@ pub unsafe fn PyVectorcall_Function(callable: *mut PyObject) -> Option<vectorcal
assert!(PyCallable_Check(callable) > 0); assert!(PyCallable_Check(callable) > 0);
let offset = (*tp).tp_vectorcall_offset; let offset = (*tp).tp_vectorcall_offset;
assert!(offset > 0); assert!(offset > 0);
let ptr = (callable as *const c_char).offset(offset) as *const Option<vectorcallfunc>; let ptr = callable.cast::<c_char>().offset(offset).cast();
*ptr *ptr
} }

View File

@ -13,7 +13,9 @@
use crate::{PyLong_AsLong, PyLong_Check, PyObject_GetAttrString, Py_DecRef}; use crate::{PyLong_AsLong, PyLong_Check, PyObject_GetAttrString, Py_DecRef};
use crate::{PyObject, PyObject_TypeCheck, PyTypeObject, Py_TYPE}; use crate::{PyObject, PyObject_TypeCheck, PyTypeObject, Py_TYPE};
use std::cell::UnsafeCell; use std::cell::UnsafeCell;
use std::os::raw::{c_char, c_int}; #[cfg(not(GraalPy))]
use std::os::raw::c_char;
use std::os::raw::c_int;
use std::ptr; use std::ptr;
#[cfg(not(PyPy))] #[cfg(not(PyPy))]
use {crate::PyCapsule_Import, std::ffi::CString}; use {crate::PyCapsule_Import, std::ffi::CString};
@ -356,7 +358,7 @@ pub unsafe fn PyDateTime_DELTA_GET_MICROSECONDS(o: *mut PyObject) -> c_int {
#[inline] #[inline]
#[cfg(GraalPy)] #[cfg(GraalPy)]
pub unsafe fn _get_attr(obj: *mut PyObject, field: &str) -> c_int { pub unsafe fn _get_attr(obj: *mut PyObject, field: &str) -> c_int {
let result = PyObject_GetAttrString(obj, field.as_ptr() as *const c_char); let result = PyObject_GetAttrString(obj, field.as_ptr().cast());
Py_DecRef(result); // the original macros are borrowing Py_DecRef(result); // the original macros are borrowing
if PyLong_Check(result) == 1 { if PyLong_Check(result) == 1 {
PyLong_AsLong(result) as c_int PyLong_AsLong(result) as c_int
@ -416,7 +418,7 @@ pub unsafe fn PyDateTime_DATE_GET_FOLD(o: *mut PyObject) -> c_int {
#[inline] #[inline]
#[cfg(GraalPy)] #[cfg(GraalPy)]
pub unsafe fn PyDateTime_DATE_GET_TZINFO(o: *mut PyObject) -> *mut PyObject { pub unsafe fn PyDateTime_DATE_GET_TZINFO(o: *mut PyObject) -> *mut PyObject {
let res = PyObject_GetAttrString(o, "tzinfo\0".as_ptr() as *const c_char); let res = PyObject_GetAttrString(o, "tzinfo\0".as_ptr().cast());
Py_DecRef(res); // the original macros are borrowing Py_DecRef(res); // the original macros are borrowing
res res
} }
@ -454,7 +456,7 @@ pub unsafe fn PyDateTime_TIME_GET_FOLD(o: *mut PyObject) -> c_int {
#[inline] #[inline]
#[cfg(GraalPy)] #[cfg(GraalPy)]
pub unsafe fn PyDateTime_TIME_GET_TZINFO(o: *mut PyObject) -> *mut PyObject { pub unsafe fn PyDateTime_TIME_GET_TZINFO(o: *mut PyObject) -> *mut PyObject {
let res = PyObject_GetAttrString(o, "tzinfo\0".as_ptr() as *const c_char); let res = PyObject_GetAttrString(o, "tzinfo\0".as_ptr().cast());
Py_DecRef(res); // the original macros are borrowing Py_DecRef(res); // the original macros are borrowing
res res
} }

View File

@ -263,7 +263,7 @@ impl<T: Element> PyBuffer<T> {
}, },
#[cfg(Py_3_11)] #[cfg(Py_3_11)]
{ {
indices.as_ptr() as *const ffi::Py_ssize_t indices.as_ptr().cast()
}, },
#[cfg(not(Py_3_11))] #[cfg(not(Py_3_11))]
{ {
@ -317,7 +317,7 @@ impl<T: Element> PyBuffer<T> {
/// However, dimensions of length 0 are possible and might need special attention. /// However, dimensions of length 0 are possible and might need special attention.
#[inline] #[inline]
pub fn shape(&self) -> &[usize] { pub fn shape(&self) -> &[usize] {
unsafe { slice::from_raw_parts(self.0.shape as *const usize, self.0.ndim as usize) } unsafe { slice::from_raw_parts(self.0.shape.cast(), self.0.ndim as usize) }
} }
/// Returns an array that holds, for each dimension, the number of bytes to skip to get to the next element in the dimension. /// Returns an array that holds, for each dimension, the number of bytes to skip to get to the next element in the dimension.
@ -361,23 +361,13 @@ impl<T: Element> PyBuffer<T> {
/// Gets whether the buffer is contiguous in C-style order (last index varies fastest when visiting items in order of memory address). /// Gets whether the buffer is contiguous in C-style order (last index varies fastest when visiting items in order of memory address).
#[inline] #[inline]
pub fn is_c_contiguous(&self) -> bool { pub fn is_c_contiguous(&self) -> bool {
unsafe { unsafe { ffi::PyBuffer_IsContiguous(&*self.0, b'C' as std::os::raw::c_char) != 0 }
ffi::PyBuffer_IsContiguous(
&*self.0 as *const ffi::Py_buffer,
b'C' as std::os::raw::c_char,
) != 0
}
} }
/// Gets whether the buffer is contiguous in Fortran-style order (first index varies fastest when visiting items in order of memory address). /// Gets whether the buffer is contiguous in Fortran-style order (first index varies fastest when visiting items in order of memory address).
#[inline] #[inline]
pub fn is_fortran_contiguous(&self) -> bool { pub fn is_fortran_contiguous(&self) -> bool {
unsafe { unsafe { ffi::PyBuffer_IsContiguous(&*self.0, b'F' as std::os::raw::c_char) != 0 }
ffi::PyBuffer_IsContiguous(
&*self.0 as *const ffi::Py_buffer,
b'F' as std::os::raw::c_char,
) != 0
}
} }
/// Gets the buffer memory as a slice. /// Gets the buffer memory as a slice.
@ -609,7 +599,7 @@ impl<T: Element> PyBuffer<T> {
}, },
#[cfg(Py_3_11)] #[cfg(Py_3_11)]
{ {
source.as_ptr() as *const raw::c_void source.as_ptr().cast()
}, },
#[cfg(not(Py_3_11))] #[cfg(not(Py_3_11))]
{ {

View File

@ -48,7 +48,6 @@ use crate::sync::GILOnceCell;
use crate::types::any::PyAnyMethods; use crate::types::any::PyAnyMethods;
use crate::types::PyType; use crate::types::PyType;
use crate::{Bound, FromPyObject, IntoPy, Py, PyAny, PyObject, PyResult, Python, ToPyObject}; use crate::{Bound, FromPyObject, IntoPy, Py, PyAny, PyObject, PyResult, Python, ToPyObject};
use std::os::raw::c_char;
#[cfg(feature = "num-bigint")] #[cfg(feature = "num-bigint")]
use num_bigint::BigInt; use num_bigint::BigInt;
@ -68,19 +67,13 @@ macro_rules! rational_conversion {
let py_numerator_obj = unsafe { let py_numerator_obj = unsafe {
Bound::from_owned_ptr_or_err( Bound::from_owned_ptr_or_err(
py, py,
ffi::PyObject_GetAttrString( ffi::PyObject_GetAttrString(obj.as_ptr(), "numerator\0".as_ptr().cast()),
obj.as_ptr(),
"numerator\0".as_ptr() as *const c_char,
),
) )
}; };
let py_denominator_obj = unsafe { let py_denominator_obj = unsafe {
Bound::from_owned_ptr_or_err( Bound::from_owned_ptr_or_err(
py, py,
ffi::PyObject_GetAttrString( ffi::PyObject_GetAttrString(obj.as_ptr(), "denominator\0".as_ptr().cast()),
obj.as_ptr(),
"denominator\0".as_ptr() as *const c_char,
),
) )
}; };
let numerator_owned = unsafe { let numerator_owned = unsafe {

View File

@ -4,8 +4,6 @@ use crate::types::PyString;
use crate::{ffi, FromPyObject, IntoPy, PyAny, PyObject, PyResult, Python, ToPyObject}; use crate::{ffi, FromPyObject, IntoPy, PyAny, PyObject, PyResult, Python, ToPyObject};
use std::borrow::Cow; use std::borrow::Cow;
use std::ffi::{OsStr, OsString}; use std::ffi::{OsStr, OsString};
#[cfg(not(windows))]
use std::os::raw::c_char;
impl ToPyObject for OsStr { impl ToPyObject for OsStr {
fn to_object(&self, py: Python<'_>) -> PyObject { fn to_object(&self, py: Python<'_>) -> PyObject {
@ -23,7 +21,7 @@ impl ToPyObject for OsStr {
#[cfg(not(target_os = "wasi"))] #[cfg(not(target_os = "wasi"))]
let bytes = std::os::unix::ffi::OsStrExt::as_bytes(self); let bytes = std::os::unix::ffi::OsStrExt::as_bytes(self);
let ptr = bytes.as_ptr() as *const c_char; let ptr = bytes.as_ptr().cast();
let len = bytes.len() as ffi::Py_ssize_t; let len = bytes.len() as ffi::Py_ssize_t;
unsafe { unsafe {
// DecodeFSDefault automatically chooses an appropriate decoding mechanism to // DecodeFSDefault automatically chooses an appropriate decoding mechanism to

View File

@ -12,7 +12,6 @@
use crate::{ffi, Bound, PyResult, Python}; use crate::{ffi, Bound, PyResult, Python};
use std::ffi::CStr; use std::ffi::CStr;
use std::ops; use std::ops;
use std::os::raw::c_char;
/// The boilerplate to convert between a Rust type and a Python exception. /// The boilerplate to convert between a Rust type and a Python exception.
#[doc(hidden)] #[doc(hidden)]
@ -682,7 +681,7 @@ impl PyUnicodeDecodeError {
unsafe { unsafe {
ffi::PyUnicodeDecodeError_Create( ffi::PyUnicodeDecodeError_Create(
encoding.as_ptr(), encoding.as_ptr(),
input.as_ptr() as *const c_char, input.as_ptr().cast(),
input.len() as ffi::Py_ssize_t, input.len() as ffi::Py_ssize_t,
range.start as ffi::Py_ssize_t, range.start as ffi::Py_ssize_t,
range.end as ffi::Py_ssize_t, range.end as ffi::Py_ssize_t,

View File

@ -318,9 +318,9 @@ impl FunctionDescription {
let kwnames: Option<Borrowed<'_, '_, PyTuple>> = let kwnames: Option<Borrowed<'_, '_, PyTuple>> =
Borrowed::from_ptr_or_opt(py, kwnames).map(|kwnames| kwnames.downcast_unchecked()); Borrowed::from_ptr_or_opt(py, kwnames).map(|kwnames| kwnames.downcast_unchecked());
if let Some(kwnames) = kwnames { if let Some(kwnames) = kwnames {
// Safety: PyArg has the same memory layout as `*mut ffi::PyObject`
let kwargs = ::std::slice::from_raw_parts( let kwargs = ::std::slice::from_raw_parts(
(args as *const PyArg<'py>).offset(nargs), // Safety: PyArg has the same memory layout as `*mut ffi::PyObject`
args.offset(nargs).cast::<PyArg<'py>>(),
kwnames.len(), kwnames.len(),
); );

View File

@ -70,8 +70,8 @@ impl ModuleDef {
}; };
let ffi_def = UnsafeCell::new(ffi::PyModuleDef { let ffi_def = UnsafeCell::new(ffi::PyModuleDef {
m_name: name.as_ptr() as *const _, m_name: name.as_ptr().cast(),
m_doc: doc.as_ptr() as *const _, m_doc: doc.as_ptr().cast(),
..INIT ..INIT
}); });

View File

@ -1,5 +1,6 @@
use crate::err::{self, PyErr, PyResult}; use crate::err::{self, PyErr, PyResult};
use crate::impl_::pycell::PyClassObject; use crate::impl_::pycell::PyClassObject;
use crate::internal_tricks::ptr_from_ref;
use crate::pycell::{PyBorrowError, PyBorrowMutError}; use crate::pycell::{PyBorrowError, PyBorrowMutError};
use crate::pyclass::boolean_struct::{False, True}; use crate::pyclass::boolean_struct::{False, True};
#[cfg(feature = "gil-refs")] #[cfg(feature = "gil-refs")]
@ -42,7 +43,7 @@ pub unsafe trait PyNativeType: Sized {
// Safety: &'py Self is expected to be a Python pointer, // Safety: &'py Self is expected to be a Python pointer,
// so has the same layout as Borrowed<'py, 'py, T> // so has the same layout as Borrowed<'py, 'py, T>
Borrowed( Borrowed(
unsafe { NonNull::new_unchecked(self as *const Self as *mut _) }, unsafe { NonNull::new_unchecked(ptr_from_ref(self) as *mut _) },
PhantomData, PhantomData,
self.py(), self.py(),
) )
@ -193,7 +194,7 @@ impl<'py> Bound<'py, PyAny> {
_py: Python<'py>, _py: Python<'py>,
ptr: &'a *mut ffi::PyObject, ptr: &'a *mut ffi::PyObject,
) -> &'a Self { ) -> &'a Self {
&*(ptr as *const *mut ffi::PyObject).cast::<Bound<'py, PyAny>>() &*ptr_from_ref(ptr).cast::<Bound<'py, PyAny>>()
} }
/// Variant of the above which returns `None` for null pointers. /// Variant of the above which returns `None` for null pointers.
@ -205,7 +206,7 @@ impl<'py> Bound<'py, PyAny> {
_py: Python<'py>, _py: Python<'py>,
ptr: &'a *mut ffi::PyObject, ptr: &'a *mut ffi::PyObject,
) -> &'a Option<Self> { ) -> &'a Option<Self> {
&*(ptr as *const *mut ffi::PyObject).cast::<Option<Bound<'py, PyAny>>>() &*ptr_from_ref(ptr).cast::<Option<Bound<'py, PyAny>>>()
} }
} }
@ -454,7 +455,7 @@ impl<'py, T> Bound<'py, T> {
pub fn as_any(&self) -> &Bound<'py, PyAny> { pub fn as_any(&self) -> &Bound<'py, PyAny> {
// Safety: all Bound<T> have the same memory layout, and all Bound<T> are valid // Safety: all Bound<T> have the same memory layout, and all Bound<T> are valid
// Bound<PyAny>, so pointer casting is valid. // Bound<PyAny>, so pointer casting is valid.
unsafe { &*(self as *const Self).cast::<Bound<'py, PyAny>>() } unsafe { &*ptr_from_ref(self).cast::<Bound<'py, PyAny>>() }
} }
/// Helper to cast to `Bound<'py, PyAny>`, transferring ownership. /// Helper to cast to `Bound<'py, PyAny>`, transferring ownership.
@ -694,7 +695,7 @@ impl<'py, T> Deref for Borrowed<'_, 'py, T> {
#[inline] #[inline]
fn deref(&self) -> &Bound<'py, T> { fn deref(&self) -> &Bound<'py, T> {
// safety: Bound has the same layout as NonNull<ffi::PyObject> // safety: Bound has the same layout as NonNull<ffi::PyObject>
unsafe { &*(&self.0 as *const _ as *const Bound<'py, T>) } unsafe { &*ptr_from_ref(&self.0).cast() }
} }
} }
@ -1097,7 +1098,7 @@ impl<T> Py<T> {
pub fn as_any(&self) -> &Py<PyAny> { pub fn as_any(&self) -> &Py<PyAny> {
// Safety: all Py<T> have the same memory layout, and all Py<T> are valid // Safety: all Py<T> have the same memory layout, and all Py<T> are valid
// Py<PyAny>, so pointer casting is valid. // Py<PyAny>, so pointer casting is valid.
unsafe { &*(self as *const Self).cast::<Py<PyAny>>() } unsafe { &*ptr_from_ref(self).cast::<Py<PyAny>>() }
} }
/// Helper to cast to `Py<PyAny>`, transferring ownership. /// Helper to cast to `Py<PyAny>`, transferring ownership.
@ -1273,7 +1274,7 @@ impl<T> Py<T> {
#[inline] #[inline]
pub fn bind<'py>(&self, _py: Python<'py>) -> &Bound<'py, T> { pub fn bind<'py>(&self, _py: Python<'py>) -> &Bound<'py, T> {
// Safety: `Bound` has the same layout as `Py` // Safety: `Bound` has the same layout as `Py`
unsafe { &*(self as *const Py<T>).cast() } unsafe { &*ptr_from_ref(self).cast() }
} }
/// Same as `bind` but takes ownership of `self`. /// Same as `bind` but takes ownership of `self`.

View File

@ -217,3 +217,9 @@ pub(crate) fn extract_c_string(
}; };
Ok(cow) Ok(cow)
} }
// TODO: use ptr::from_ref on MSRV 1.76
#[inline]
pub(crate) const fn ptr_from_ref<T>(t: &T) -> *const T {
t as *const T
}

View File

@ -214,7 +214,7 @@ macro_rules! append_to_inittab {
); );
} }
$crate::ffi::PyImport_AppendInittab( $crate::ffi::PyImport_AppendInittab(
$module::__PYO3_NAME.as_ptr() as *const ::std::os::raw::c_char, $module::__PYO3_NAME.as_ptr().cast(),
::std::option::Option::Some($module::__pyo3_init), ::std::option::Option::Some($module::__pyo3_init),
); );
} }

View File

@ -652,7 +652,7 @@ impl<'py> Python<'py> {
) -> PyResult<Bound<'py, PyAny>> { ) -> PyResult<Bound<'py, PyAny>> {
let code = CString::new(code)?; let code = CString::new(code)?;
unsafe { unsafe {
let mptr = ffi::PyImport_AddModule("__main__\0".as_ptr() as *const _); let mptr = ffi::PyImport_AddModule("__main__\0".as_ptr().cast());
if mptr.is_null() { if mptr.is_null() {
return Err(PyErr::fetch(self)); return Err(PyErr::fetch(self));
} }

View File

@ -202,6 +202,7 @@ use crate::types::any::PyAnyMethods;
use crate::{ use crate::{
conversion::ToPyObject, conversion::ToPyObject,
impl_::pyclass::PyClassImpl, impl_::pyclass::PyClassImpl,
internal_tricks::ptr_from_ref,
pyclass::boolean_struct::True, pyclass::boolean_struct::True,
pyclass_init::PyClassInitializer, pyclass_init::PyClassInitializer,
type_object::{PyLayout, PySizedLayout}, type_object::{PyLayout, PySizedLayout},
@ -511,7 +512,7 @@ where
#[allow(deprecated)] #[allow(deprecated)]
unsafe impl<T: PyClass> AsPyPointer for PyCell<T> { unsafe impl<T: PyClass> AsPyPointer for PyCell<T> {
fn as_ptr(&self) -> *mut ffi::PyObject { fn as_ptr(&self) -> *mut ffi::PyObject {
(self as *const _) as *mut _ ptr_from_ref(self) as *mut _
} }
} }

View File

@ -3,17 +3,17 @@ use pyo3_ffi::PyType_IS_GC;
use crate::{ use crate::{
exceptions::PyTypeError, exceptions::PyTypeError,
ffi, ffi,
impl_::pycell::PyClassObject,
impl_::pyclass::{
assign_sequence_item_from_mapping, get_sequence_item_from_mapping, tp_dealloc,
tp_dealloc_with_gc, PyClassItemsIter,
},
impl_::{ impl_::{
pycell::PyClassObject,
pyclass::{
assign_sequence_item_from_mapping, get_sequence_item_from_mapping, tp_dealloc,
tp_dealloc_with_gc, PyClassItemsIter,
},
pymethods::{get_doc, get_name, Getter, Setter}, pymethods::{get_doc, get_name, Getter, Setter},
trampoline::trampoline, trampoline::trampoline,
}, },
types::typeobject::PyTypeMethods, internal_tricks::ptr_from_ref,
types::PyType, types::{typeobject::PyTypeMethods, PyType},
Py, PyClass, PyGetterDef, PyMethodDefType, PyResult, PySetterDef, PyTypeInfo, Python, Py, PyClass, PyGetterDef, PyMethodDefType, PyResult, PySetterDef, PyTypeInfo, Python,
}; };
use std::{ use std::{
@ -608,7 +608,7 @@ impl GetSetDefType {
slf: *mut ffi::PyObject, slf: *mut ffi::PyObject,
closure: *mut c_void, closure: *mut c_void,
) -> *mut ffi::PyObject { ) -> *mut ffi::PyObject {
let getset: &GetterAndSetter = &*(closure as *const GetterAndSetter); let getset: &GetterAndSetter = &*closure.cast();
trampoline(|py| (getset.getter)(py, slf)) trampoline(|py| (getset.getter)(py, slf))
} }
@ -617,13 +617,13 @@ impl GetSetDefType {
value: *mut ffi::PyObject, value: *mut ffi::PyObject,
closure: *mut c_void, closure: *mut c_void,
) -> c_int { ) -> c_int {
let getset: &GetterAndSetter = &*(closure as *const GetterAndSetter); let getset: &GetterAndSetter = &*closure.cast();
trampoline(|py| (getset.setter)(py, slf, value)) trampoline(|py| (getset.setter)(py, slf, value))
} }
( (
Some(getset_getter), Some(getset_getter),
Some(getset_setter), Some(getset_setter),
closure.as_ref() as *const GetterAndSetter as _, ptr_from_ref::<GetterAndSetter>(closure) as *mut _,
) )
} }
}; };

View File

@ -4,6 +4,7 @@ use crate::err::{DowncastError, DowncastIntoError, PyErr, PyResult};
use crate::exceptions::{PyAttributeError, PyTypeError}; use crate::exceptions::{PyAttributeError, PyTypeError};
use crate::ffi_ptr_ext::FfiPtrExt; use crate::ffi_ptr_ext::FfiPtrExt;
use crate::instance::Bound; use crate::instance::Bound;
use crate::internal_tricks::ptr_from_ref;
use crate::py_result_ext::PyResultExt; use crate::py_result_ext::PyResultExt;
use crate::type_object::{PyTypeCheck, PyTypeInfo}; use crate::type_object::{PyTypeCheck, PyTypeInfo};
#[cfg(not(any(PyPy, GraalPy)))] #[cfg(not(any(PyPy, GraalPy)))]
@ -912,7 +913,7 @@ impl PyAny {
/// when they are finished with the pointer. /// when they are finished with the pointer.
#[inline] #[inline]
pub fn as_ptr(&self) -> *mut ffi::PyObject { pub fn as_ptr(&self) -> *mut ffi::PyObject {
self as *const PyAny as *mut ffi::PyObject ptr_from_ref(self) as *mut ffi::PyObject
} }
/// Returns an owned raw FFI pointer represented by self. /// Returns an owned raw FFI pointer represented by self.
@ -2211,7 +2212,7 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> {
#[inline] #[inline]
unsafe fn downcast_unchecked<T>(&self) -> &Bound<'py, T> { unsafe fn downcast_unchecked<T>(&self) -> &Bound<'py, T> {
&*(self as *const Bound<'py, PyAny>).cast() &*ptr_from_ref(self).cast()
} }
#[inline] #[inline]

View File

@ -6,7 +6,6 @@ use crate::types::any::PyAnyMethods;
use crate::{ffi, PyAny, Python}; use crate::{ffi, PyAny, Python};
#[cfg(feature = "gil-refs")] #[cfg(feature = "gil-refs")]
use crate::{AsPyPointer, PyNativeType}; use crate::{AsPyPointer, PyNativeType};
use std::os::raw::c_char;
use std::slice; use std::slice;
/// Represents a Python `bytearray`. /// Represents a Python `bytearray`.
@ -20,7 +19,7 @@ impl PyByteArray {
/// ///
/// The byte string is initialized by copying the data from the `&[u8]`. /// The byte string is initialized by copying the data from the `&[u8]`.
pub fn new_bound<'py>(py: Python<'py>, src: &[u8]) -> Bound<'py, PyByteArray> { pub fn new_bound<'py>(py: Python<'py>, src: &[u8]) -> Bound<'py, PyByteArray> {
let ptr = src.as_ptr() as *const c_char; let ptr = src.as_ptr().cast();
let len = src.len() as ffi::Py_ssize_t; let len = src.len() as ffi::Py_ssize_t;
unsafe { unsafe {
ffi::PyByteArray_FromStringAndSize(ptr, len) ffi::PyByteArray_FromStringAndSize(ptr, len)

View File

@ -5,7 +5,6 @@ use crate::types::any::PyAnyMethods;
use crate::PyNativeType; use crate::PyNativeType;
use crate::{ffi, Py, PyAny, PyResult, Python}; use crate::{ffi, Py, PyAny, PyResult, Python};
use std::ops::Index; use std::ops::Index;
use std::os::raw::c_char;
use std::slice::SliceIndex; use std::slice::SliceIndex;
use std::str; use std::str;
@ -23,7 +22,7 @@ impl PyBytes {
/// ///
/// Panics if out of memory. /// Panics if out of memory.
pub fn new_bound<'p>(py: Python<'p>, s: &[u8]) -> Bound<'p, PyBytes> { pub fn new_bound<'p>(py: Python<'p>, s: &[u8]) -> Bound<'p, PyBytes> {
let ptr = s.as_ptr() as *const c_char; let ptr = s.as_ptr().cast();
let len = s.len() as ffi::Py_ssize_t; let len = s.len() as ffi::Py_ssize_t;
unsafe { unsafe {
ffi::PyBytes_FromStringAndSize(ptr, len) ffi::PyBytes_FromStringAndSize(ptr, len)
@ -85,7 +84,7 @@ impl PyBytes {
/// `std::slice::from_raw_parts`, this is /// `std::slice::from_raw_parts`, this is
/// unsafe](https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html#safety). /// 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 bound_from_ptr(py: Python<'_>, ptr: *const u8, len: usize) -> Bound<'_, PyBytes> {
ffi::PyBytes_FromStringAndSize(ptr as *const _, len as isize) ffi::PyBytes_FromStringAndSize(ptr.cast(), len as isize)
.assume_owned(py) .assume_owned(py)
.downcast_into_unchecked() .downcast_into_unchecked()
} }

View File

@ -10,7 +10,6 @@ use crate::types::PyBytes;
use crate::PyNativeType; use crate::PyNativeType;
use crate::{ffi, Bound, IntoPy, Py, PyAny, PyResult, Python}; use crate::{ffi, Bound, IntoPy, Py, PyAny, PyResult, Python};
use std::borrow::Cow; use std::borrow::Cow;
use std::os::raw::c_char;
use std::str; use std::str;
/// Represents raw data backing a Python `str`. /// Represents raw data backing a Python `str`.
@ -37,16 +36,10 @@ impl<'a> PyStringData<'a> {
match self { match self {
Self::Ucs1(s) => s, Self::Ucs1(s) => s,
Self::Ucs2(s) => unsafe { Self::Ucs2(s) => unsafe {
std::slice::from_raw_parts( std::slice::from_raw_parts(s.as_ptr().cast(), s.len() * self.value_width_bytes())
s.as_ptr() as *const u8,
s.len() * self.value_width_bytes(),
)
}, },
Self::Ucs4(s) => unsafe { Self::Ucs4(s) => unsafe {
std::slice::from_raw_parts( std::slice::from_raw_parts(s.as_ptr().cast(), s.len() * self.value_width_bytes())
s.as_ptr() as *const u8,
s.len() * self.value_width_bytes(),
)
}, },
} }
} }
@ -141,7 +134,7 @@ impl PyString {
/// ///
/// Panics if out of memory. /// Panics if out of memory.
pub fn new_bound<'py>(py: Python<'py>, s: &str) -> Bound<'py, PyString> { pub fn new_bound<'py>(py: Python<'py>, s: &str) -> Bound<'py, PyString> {
let ptr = s.as_ptr() as *const c_char; let ptr = s.as_ptr().cast();
let len = s.len() as ffi::Py_ssize_t; let len = s.len() as ffi::Py_ssize_t;
unsafe { unsafe {
ffi::PyUnicode_FromStringAndSize(ptr, len) ffi::PyUnicode_FromStringAndSize(ptr, len)
@ -159,7 +152,7 @@ impl PyString {
/// ///
/// Panics if out of memory. /// Panics if out of memory.
pub fn intern_bound<'py>(py: Python<'py>, s: &str) -> Bound<'py, PyString> { pub fn intern_bound<'py>(py: Python<'py>, s: &str) -> Bound<'py, PyString> {
let ptr = s.as_ptr() as *const c_char; let ptr = s.as_ptr().cast();
let len = s.len() as ffi::Py_ssize_t; let len = s.len() as ffi::Py_ssize_t;
unsafe { unsafe {
let mut ob = ffi::PyUnicode_FromStringAndSize(ptr, len); let mut ob = ffi::PyUnicode_FromStringAndSize(ptr, len);
@ -181,8 +174,8 @@ impl PyString {
unsafe { unsafe {
ffi::PyUnicode_FromEncodedObject( ffi::PyUnicode_FromEncodedObject(
src.as_ptr(), src.as_ptr(),
encoding.as_ptr() as *const c_char, encoding.as_ptr().cast(),
errors.as_ptr() as *const c_char, errors.as_ptr().cast(),
) )
.assume_owned_or_err(src.py()) .assume_owned_or_err(src.py())
.downcast_into_unchecked() .downcast_into_unchecked()
@ -607,7 +600,7 @@ mod tests {
let ptr = unsafe { let ptr = unsafe {
crate::ffi::PyUnicode_FromKindAndData( crate::ffi::PyUnicode_FromKindAndData(
crate::ffi::PyUnicode_1BYTE_KIND as _, crate::ffi::PyUnicode_1BYTE_KIND as _,
buffer.as_ptr() as *const _, buffer.as_ptr().cast(),
2, 2,
) )
}; };
@ -651,7 +644,7 @@ mod tests {
let ptr = unsafe { let ptr = unsafe {
crate::ffi::PyUnicode_FromKindAndData( crate::ffi::PyUnicode_FromKindAndData(
crate::ffi::PyUnicode_2BYTE_KIND as _, crate::ffi::PyUnicode_2BYTE_KIND as _,
buffer.as_ptr() as *const _, buffer.as_ptr().cast(),
2, 2,
) )
}; };
@ -692,7 +685,7 @@ mod tests {
let ptr = unsafe { let ptr = unsafe {
crate::ffi::PyUnicode_FromKindAndData( crate::ffi::PyUnicode_FromKindAndData(
crate::ffi::PyUnicode_4BYTE_KIND as _, crate::ffi::PyUnicode_4BYTE_KIND as _,
buffer.as_ptr() as *const _, buffer.as_ptr().cast(),
2, 2,
) )
}; };

View File

@ -388,13 +388,10 @@ impl<'py> PyTupleMethods<'py> for Bound<'py, PyTuple> {
#[cfg(not(any(Py_LIMITED_API, GraalPy)))] #[cfg(not(any(Py_LIMITED_API, GraalPy)))]
fn as_slice(&self) -> &[Bound<'py, PyAny>] { fn as_slice(&self) -> &[Bound<'py, PyAny>] {
// This is safe because Bound<'py, PyAny> has the same memory layout as *mut ffi::PyObject, // SAFETY: self is known to be a tuple object, and tuples are immutable
// and because tuples are immutable. let items = unsafe { &(*self.as_ptr().cast::<ffi::PyTupleObject>()).ob_item };
unsafe { // SAFETY: Bound<'py, PyAny> has the same memory layout as *mut ffi::PyObject
let ptr = self.as_ptr() as *mut ffi::PyTupleObject; unsafe { std::slice::from_raw_parts(items.as_ptr().cast(), self.len()) }
let slice = std::slice::from_raw_parts((*ptr).ob_item.as_ptr(), self.len());
&*(slice as *const [*mut ffi::PyObject] as *const [Bound<'py, PyAny>])
}
} }
#[inline] #[inline]