Skip to content

Commit

Permalink
refactor: use ptr_from_ref and ptr .cast()
Browse files Browse the repository at this point in the history
  • Loading branch information
davidhewitt committed Jun 7, 2024
1 parent fbb6f20 commit d6ea3c1
Show file tree
Hide file tree
Showing 20 changed files with 64 additions and 91 deletions.
5 changes: 1 addition & 4 deletions pyo3-ffi/src/abstract_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,7 @@ extern "C" {
#[cfg(not(any(Py_3_8, PyPy)))]
#[inline]
pub unsafe fn PyIter_Check(o: *mut PyObject) -> c_int {
crate::PyObject_HasAttrString(
crate::Py_TYPE(o).cast(),
"__next__\0".as_ptr() as *const c_char,
)
crate::PyObject_HasAttrString(crate::Py_TYPE(o).cast(), "__next__\0".as_ptr().cast())
}

extern "C" {
Expand Down
2 changes: 1 addition & 1 deletion pyo3-ffi/src/cpython/abstract_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ pub unsafe fn PyVectorcall_Function(callable: *mut PyObject) -> Option<vectorcal
assert!(PyCallable_Check(callable) > 0);
let offset = (*tp).tp_vectorcall_offset;
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
}

Expand Down
6 changes: 3 additions & 3 deletions pyo3-ffi/src/datetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ pub unsafe fn PyDateTime_DELTA_GET_MICROSECONDS(o: *mut PyObject) -> c_int {
#[inline]
#[cfg(GraalPy)]
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
if PyLong_Check(result) == 1 {
PyLong_AsLong(result) as c_int
Expand Down Expand Up @@ -416,7 +416,7 @@ pub unsafe fn PyDateTime_DATE_GET_FOLD(o: *mut PyObject) -> c_int {
#[inline]
#[cfg(GraalPy)]
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
res
}
Expand Down Expand Up @@ -454,7 +454,7 @@ pub unsafe fn PyDateTime_TIME_GET_FOLD(o: *mut PyObject) -> c_int {
#[inline]
#[cfg(GraalPy)]
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
res
}
Expand Down
20 changes: 5 additions & 15 deletions src/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ impl<T: Element> PyBuffer<T> {
},
#[cfg(Py_3_11)]
{
indices.as_ptr() as *const ffi::Py_ssize_t
indices.as_ptr().cast()
},
#[cfg(not(Py_3_11))]
{
Expand Down Expand Up @@ -317,7 +317,7 @@ impl<T: Element> PyBuffer<T> {
/// However, dimensions of length 0 are possible and might need special attention.
#[inline]
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.
Expand Down Expand Up @@ -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).
#[inline]
pub fn is_c_contiguous(&self) -> bool {
unsafe {
ffi::PyBuffer_IsContiguous(
&*self.0 as *const ffi::Py_buffer,
b'C' as std::os::raw::c_char,
) != 0
}
unsafe { ffi::PyBuffer_IsContiguous(&*self.0, 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).
#[inline]
pub fn is_fortran_contiguous(&self) -> bool {
unsafe {
ffi::PyBuffer_IsContiguous(
&*self.0 as *const ffi::Py_buffer,
b'F' as std::os::raw::c_char,
) != 0
}
unsafe { ffi::PyBuffer_IsContiguous(&*self.0, b'F' as std::os::raw::c_char) != 0 }
}

/// Gets the buffer memory as a slice.
Expand Down Expand Up @@ -609,7 +599,7 @@ impl<T: Element> PyBuffer<T> {
},
#[cfg(Py_3_11)]
{
source.as_ptr() as *const raw::c_void
source.as_ptr().cast()
},
#[cfg(not(Py_3_11))]
{
Expand Down
11 changes: 2 additions & 9 deletions src/conversions/num_rational.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ use crate::sync::GILOnceCell;
use crate::types::any::PyAnyMethods;
use crate::types::PyType;
use crate::{Bound, FromPyObject, IntoPy, Py, PyAny, PyObject, PyResult, Python, ToPyObject};
use std::os::raw::c_char;

#[cfg(feature = "num-bigint")]
use num_bigint::BigInt;
Expand All @@ -68,19 +67,13 @@ macro_rules! rational_conversion {
let py_numerator_obj = unsafe {
Bound::from_owned_ptr_or_err(
py,
ffi::PyObject_GetAttrString(
obj.as_ptr(),
"numerator\0".as_ptr() as *const c_char,
),
ffi::PyObject_GetAttrString(obj.as_ptr(), "numerator\0".as_ptr().cast()),
)
};
let py_denominator_obj = unsafe {
Bound::from_owned_ptr_or_err(
py,
ffi::PyObject_GetAttrString(
obj.as_ptr(),
"denominator\0".as_ptr() as *const c_char,
),
ffi::PyObject_GetAttrString(obj.as_ptr(), "denominator\0".as_ptr().cast()),
)
};
let numerator_owned = unsafe {
Expand Down
4 changes: 1 addition & 3 deletions src/conversions/std/osstr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ use crate::types::PyString;
use crate::{ffi, FromPyObject, IntoPy, PyAny, PyObject, PyResult, Python, ToPyObject};
use std::borrow::Cow;
use std::ffi::{OsStr, OsString};
#[cfg(not(windows))]
use std::os::raw::c_char;

impl ToPyObject for OsStr {
fn to_object(&self, py: Python<'_>) -> PyObject {
Expand All @@ -23,7 +21,7 @@ impl ToPyObject for OsStr {
#[cfg(not(target_os = "wasi"))]
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;
unsafe {
// DecodeFSDefault automatically chooses an appropriate decoding mechanism to
Expand Down
3 changes: 1 addition & 2 deletions src/exceptions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
use crate::{ffi, Bound, PyResult, Python};
use std::ffi::CStr;
use std::ops;
use std::os::raw::c_char;

/// The boilerplate to convert between a Rust type and a Python exception.
#[doc(hidden)]
Expand Down Expand Up @@ -682,7 +681,7 @@ impl PyUnicodeDecodeError {
unsafe {
ffi::PyUnicodeDecodeError_Create(
encoding.as_ptr(),
input.as_ptr() as *const c_char,
input.as_ptr().cast(),
input.len() as ffi::Py_ssize_t,
range.start as ffi::Py_ssize_t,
range.end as ffi::Py_ssize_t,
Expand Down
4 changes: 2 additions & 2 deletions src/impl_/extract_argument.rs
Original file line number Diff line number Diff line change
Expand Up @@ -318,9 +318,9 @@ impl FunctionDescription {
let kwnames: Option<Borrowed<'_, '_, PyTuple>> =
Borrowed::from_ptr_or_opt(py, kwnames).map(|kwnames| kwnames.downcast_unchecked());
if let Some(kwnames) = kwnames {
// Safety: PyArg has the same memory layout as `*mut ffi::PyObject`
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(),
);

Expand Down
4 changes: 2 additions & 2 deletions src/impl_/pymodule.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ impl ModuleDef {
};

let ffi_def = UnsafeCell::new(ffi::PyModuleDef {
m_name: name.as_ptr() as *const _,
m_doc: doc.as_ptr() as *const _,
m_name: name.as_ptr().cast(),
m_doc: doc.as_ptr().cast(),
..INIT
});

Expand Down
15 changes: 8 additions & 7 deletions src/instance.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::err::{self, PyErr, PyResult};
use crate::impl_::pycell::PyClassObject;
use crate::internal_tricks::ptr_from_ref;
use crate::pycell::{PyBorrowError, PyBorrowMutError};
use crate::pyclass::boolean_struct::{False, True};
#[cfg(feature = "gil-refs")]
Expand Down Expand Up @@ -42,7 +43,7 @@ pub unsafe trait PyNativeType: Sized {
// Safety: &'py Self is expected to be a Python pointer,
// so has the same layout as Borrowed<'py, 'py, T>
Borrowed(
unsafe { NonNull::new_unchecked(self as *const Self as *mut _) },
unsafe { NonNull::new_unchecked(ptr_from_ref(self) as *mut _) },
PhantomData,
self.py(),
)
Expand Down Expand Up @@ -193,7 +194,7 @@ impl<'py> Bound<'py, PyAny> {
_py: Python<'py>,
ptr: &'a *mut ffi::PyObject,
) -> &'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.
Expand All @@ -205,7 +206,7 @@ impl<'py> Bound<'py, PyAny> {
_py: Python<'py>,
ptr: &'a *mut ffi::PyObject,
) -> &'a Option<Self> {
&*(ptr as *const *mut ffi::PyObject).cast::<Option<Bound<'py, PyAny>>>()
&*ptr_from_ref(ptr).cast::<Option<Bound<'py, PyAny>>>()
}
}

Expand Down Expand Up @@ -454,7 +455,7 @@ impl<'py, T> Bound<'py, T> {
pub fn as_any(&self) -> &Bound<'py, PyAny> {
// Safety: all Bound<T> have the same memory layout, and all Bound<T> are 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.
Expand Down Expand Up @@ -694,7 +695,7 @@ impl<'py, T> Deref for Borrowed<'_, 'py, T> {
#[inline]
fn deref(&self) -> &Bound<'py, T> {
// 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() }
}
}

Expand Down Expand Up @@ -1097,7 +1098,7 @@ impl<T> Py<T> {
pub fn as_any(&self) -> &Py<PyAny> {
// Safety: all Py<T> have the same memory layout, and all Py<T> are 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.
Expand Down Expand Up @@ -1273,7 +1274,7 @@ impl<T> Py<T> {
#[inline]
pub fn bind<'py>(&self, _py: Python<'py>) -> &Bound<'py, T> {
// 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`.
Expand Down
6 changes: 6 additions & 0 deletions src/internal_tricks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,3 +217,9 @@ pub(crate) fn extract_c_string(
};
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
}
2 changes: 1 addition & 1 deletion src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ macro_rules! append_to_inittab {
);
}
$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),
);
}
Expand Down
2 changes: 1 addition & 1 deletion src/marker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -652,7 +652,7 @@ impl<'py> Python<'py> {
) -> PyResult<Bound<'py, PyAny>> {
let code = CString::new(code)?;
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() {
return Err(PyErr::fetch(self));
}
Expand Down
2 changes: 1 addition & 1 deletion src/pycell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,7 @@ where
#[allow(deprecated)]
unsafe impl<T: PyClass> AsPyPointer for PyCell<T> {
fn as_ptr(&self) -> *mut ffi::PyObject {
(self as *const _) as *mut _
ptr_from_ref(self) as *mut _
}
}

Expand Down
20 changes: 10 additions & 10 deletions src/pyclass/create_type_object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ use pyo3_ffi::PyType_IS_GC;
use crate::{
exceptions::PyTypeError,
ffi,
impl_::pycell::PyClassObject,
impl_::pyclass::{
assign_sequence_item_from_mapping, get_sequence_item_from_mapping, tp_dealloc,
tp_dealloc_with_gc, PyClassItemsIter,
},
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},
trampoline::trampoline,
},
types::typeobject::PyTypeMethods,
types::PyType,
internal_tricks::ptr_from_ref,
types::{typeobject::PyTypeMethods, PyType},
Py, PyClass, PyGetterDef, PyMethodDefType, PyResult, PySetterDef, PyTypeInfo, Python,
};
use std::{
Expand Down Expand Up @@ -608,7 +608,7 @@ impl GetSetDefType {
slf: *mut ffi::PyObject,
closure: *mut c_void,
) -> *mut ffi::PyObject {
let getset: &GetterAndSetter = &*(closure as *const GetterAndSetter);
let getset: &GetterAndSetter = &*closure.cast();
trampoline(|py| (getset.getter)(py, slf))
}

Expand All @@ -617,13 +617,13 @@ impl GetSetDefType {
value: *mut ffi::PyObject,
closure: *mut c_void,
) -> c_int {
let getset: &GetterAndSetter = &*(closure as *const GetterAndSetter);
let getset: &GetterAndSetter = &*closure.cast();
trampoline(|py| (getset.setter)(py, slf, value))
}
(
Some(getset_getter),
Some(getset_setter),
closure.as_ref() as *const GetterAndSetter as _,
ptr_from_ref::<GetterAndSetter>(closure) as *mut _,
)
}
};
Expand Down
5 changes: 3 additions & 2 deletions src/types/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::err::{DowncastError, DowncastIntoError, PyErr, PyResult};
use crate::exceptions::{PyAttributeError, PyTypeError};
use crate::ffi_ptr_ext::FfiPtrExt;
use crate::instance::Bound;
use crate::internal_tricks::ptr_from_ref;
use crate::py_result_ext::PyResultExt;
use crate::type_object::{PyTypeCheck, PyTypeInfo};
#[cfg(not(any(PyPy, GraalPy)))]
Expand Down Expand Up @@ -912,7 +913,7 @@ impl PyAny {
/// when they are finished with the pointer.
#[inline]
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.
Expand Down Expand Up @@ -2211,7 +2212,7 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> {

#[inline]
unsafe fn downcast_unchecked<T>(&self) -> &Bound<'py, T> {
&*(self as *const Bound<'py, PyAny>).cast()
&*ptr_from_ref(self).cast()
}

#[inline]
Expand Down
3 changes: 1 addition & 2 deletions src/types/bytearray.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use crate::types::any::PyAnyMethods;
use crate::{ffi, PyAny, Python};
#[cfg(feature = "gil-refs")]
use crate::{AsPyPointer, PyNativeType};
use std::os::raw::c_char;
use std::slice;

/// Represents a Python `bytearray`.
Expand All @@ -20,7 +19,7 @@ impl PyByteArray {
///
/// 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> {
let ptr = src.as_ptr() as *const c_char;
let ptr = src.as_ptr().cast();
let len = src.len() as ffi::Py_ssize_t;
unsafe {
ffi::PyByteArray_FromStringAndSize(ptr, len)
Expand Down
Loading

0 comments on commit d6ea3c1

Please sign in to comment.