move unsafe block inside error_on_minusone calls

This commit is contained in:
David Hewitt 2023-07-04 20:50:54 +01:00
parent 43477a8e30
commit 76f3a395ef
13 changed files with 154 additions and 189 deletions

View file

@ -193,14 +193,13 @@ impl<T: Element> PyBuffer<T> {
pub fn get(obj: &PyAny) -> PyResult<PyBuffer<T>> { pub fn get(obj: &PyAny) -> PyResult<PyBuffer<T>> {
// TODO: use nightly API Box::new_uninit() once stable // TODO: use nightly API Box::new_uninit() once stable
let mut buf = Box::new(mem::MaybeUninit::uninit()); let mut buf = Box::new(mem::MaybeUninit::uninit());
let buf: Box<ffi::Py_buffer> = unsafe { let buf: Box<ffi::Py_buffer> = {
err::error_on_minusone( err::error_on_minusone(obj.py(), unsafe {
obj.py(), ffi::PyObject_GetBuffer(obj.as_ptr(), buf.as_mut_ptr(), ffi::PyBUF_FULL_RO)
ffi::PyObject_GetBuffer(obj.as_ptr(), buf.as_mut_ptr(), ffi::PyBUF_FULL_RO), })?;
)?;
// Safety: buf is initialized by PyObject_GetBuffer. // Safety: buf is initialized by PyObject_GetBuffer.
// TODO: use nightly API Box::assume_init() once stable // TODO: use nightly API Box::assume_init() once stable
mem::transmute(buf) unsafe { mem::transmute(buf) }
}; };
// Create PyBuffer immediately so that if validation checks fail, the PyBuffer::drop code // Create PyBuffer immediately so that if validation checks fail, the PyBuffer::drop code
// will call PyBuffer_Release (thus avoiding any leaks). // will call PyBuffer_Release (thus avoiding any leaks).
@ -493,9 +492,8 @@ impl<T: Element> PyBuffer<T> {
self.item_count() self.item_count()
))); )));
} }
unsafe {
err::error_on_minusone( err::error_on_minusone(py, unsafe {
py,
ffi::PyBuffer_ToContiguous( ffi::PyBuffer_ToContiguous(
target.as_ptr() as *mut raw::c_void, target.as_ptr() as *mut raw::c_void,
#[cfg(Py_3_11)] #[cfg(Py_3_11)]
@ -506,9 +504,8 @@ impl<T: Element> PyBuffer<T> {
}, },
self.0.len, self.0.len,
fort as std::os::raw::c_char, fort as std::os::raw::c_char,
),
) )
} })
} }
/// Copies the buffer elements to a newly allocated vector. /// Copies the buffer elements to a newly allocated vector.
@ -530,11 +527,10 @@ impl<T: Element> PyBuffer<T> {
fn _to_vec(&self, py: Python<'_>, fort: u8) -> PyResult<Vec<T>> { fn _to_vec(&self, py: Python<'_>, fort: u8) -> PyResult<Vec<T>> {
let item_count = self.item_count(); let item_count = self.item_count();
let mut vec: Vec<T> = Vec::with_capacity(item_count); let mut vec: Vec<T> = Vec::with_capacity(item_count);
unsafe {
// Copy the buffer into the uninitialized space in the vector. // Copy the buffer into the uninitialized space in the vector.
// Due to T:Copy, we don't need to be concerned with Drop impls. // Due to T:Copy, we don't need to be concerned with Drop impls.
err::error_on_minusone( err::error_on_minusone(py, unsafe {
py,
ffi::PyBuffer_ToContiguous( ffi::PyBuffer_ToContiguous(
vec.as_ptr() as *mut raw::c_void, vec.as_ptr() as *mut raw::c_void,
#[cfg(Py_3_11)] #[cfg(Py_3_11)]
@ -545,11 +541,10 @@ impl<T: Element> PyBuffer<T> {
}, },
self.0.len, self.0.len,
fort as std::os::raw::c_char, fort as std::os::raw::c_char,
), )
)?; })?;
// set vector length to mark the now-initialized space as usable // set vector length to mark the now-initialized space as usable
vec.set_len(item_count); unsafe { vec.set_len(item_count) };
}
Ok(vec) Ok(vec)
} }
@ -591,9 +586,8 @@ impl<T: Element> PyBuffer<T> {
self.item_count() self.item_count()
))); )));
} }
unsafe {
err::error_on_minusone( err::error_on_minusone(py, unsafe {
py,
ffi::PyBuffer_FromContiguous( ffi::PyBuffer_FromContiguous(
#[cfg(Py_3_11)] #[cfg(Py_3_11)]
&*self.0, &*self.0,
@ -611,9 +605,8 @@ impl<T: Element> PyBuffer<T> {
}, },
self.0.len, self.0.len,
fort as std::os::raw::c_char, fort as std::os::raw::c_char,
),
) )
} })
} }
/// Releases the buffer object, freeing the reference to the Python object /// Releases the buffer object, freeing the reference to the Python object

View file

@ -178,16 +178,18 @@ mod fast_128bit_int_conversion {
} }
impl IntoPy<PyObject> for $rust_type { impl IntoPy<PyObject> for $rust_type {
fn into_py(self, py: Python<'_>) -> PyObject { fn into_py(self, py: Python<'_>) -> PyObject {
unsafe {
// Always use little endian // Always use little endian
let bytes = self.to_le_bytes(); let bytes = self.to_le_bytes();
let obj = ffi::_PyLong_FromByteArray( unsafe {
PyObject::from_owned_ptr(
py,
ffi::_PyLong_FromByteArray(
bytes.as_ptr() as *const std::os::raw::c_uchar, bytes.as_ptr() as *const std::os::raw::c_uchar,
bytes.len(), bytes.len(),
1, 1,
$is_signed, $is_signed,
); ),
PyObject::from_owned_ptr(py, obj) )
} }
} }
@ -199,24 +201,21 @@ mod fast_128bit_int_conversion {
impl<'source> FromPyObject<'source> for $rust_type { impl<'source> FromPyObject<'source> for $rust_type {
fn extract(ob: &'source PyAny) -> PyResult<$rust_type> { fn extract(ob: &'source PyAny) -> PyResult<$rust_type> {
unsafe { let num = unsafe {
let num = ffi::PyNumber_Index(ob.as_ptr()); PyObject::from_owned_ptr_or_err(ob.py(), ffi::PyNumber_Index(ob.as_ptr()))?
if num.is_null() { };
return Err(PyErr::fetch(ob.py()));
}
let mut buffer = [0; std::mem::size_of::<$rust_type>()]; let mut buffer = [0; std::mem::size_of::<$rust_type>()];
let ok = ffi::_PyLong_AsByteArray( crate::err::error_on_minusone(ob.py(), unsafe {
num as *mut ffi::PyLongObject, ffi::_PyLong_AsByteArray(
num.as_ptr() as *mut ffi::PyLongObject,
buffer.as_mut_ptr(), buffer.as_mut_ptr(),
buffer.len(), buffer.len(),
1, 1,
$is_signed, $is_signed,
); )
ffi::Py_DECREF(num); })?;
crate::err::error_on_minusone(ob.py(), ok)?;
Ok(<$rust_type>::from_le_bytes(buffer)) Ok(<$rust_type>::from_le_bytes(buffer))
} }
}
#[cfg(feature = "experimental-inspect")] #[cfg(feature = "experimental-inspect")]
fn type_input() -> TypeInfo { fn type_input() -> TypeInfo {

View file

@ -529,16 +529,13 @@ impl PyErr {
/// ``` /// ```
pub fn warn(py: Python<'_>, category: &PyAny, message: &str, stacklevel: i32) -> PyResult<()> { pub fn warn(py: Python<'_>, category: &PyAny, message: &str, stacklevel: i32) -> PyResult<()> {
let message = CString::new(message)?; let message = CString::new(message)?;
unsafe { error_on_minusone(py, unsafe {
error_on_minusone(
py,
ffi::PyErr_WarnEx( ffi::PyErr_WarnEx(
category.as_ptr(), category.as_ptr(),
message.as_ptr(), message.as_ptr(),
stacklevel as ffi::Py_ssize_t, stacklevel as ffi::Py_ssize_t,
),
) )
} })
} }
/// Issues a warning message, with more control over the warning attributes. /// Issues a warning message, with more control over the warning attributes.
@ -569,9 +566,7 @@ impl PyErr {
None => std::ptr::null_mut(), None => std::ptr::null_mut(),
Some(obj) => obj.as_ptr(), Some(obj) => obj.as_ptr(),
}; };
unsafe { error_on_minusone(py, unsafe {
error_on_minusone(
py,
ffi::PyErr_WarnExplicit( ffi::PyErr_WarnExplicit(
category.as_ptr(), category.as_ptr(),
message.as_ptr(), message.as_ptr(),
@ -579,9 +574,8 @@ impl PyErr {
lineno, lineno,
module_ptr, module_ptr,
registry, registry,
),
) )
} })
} }
/// Clone the PyErr. This requires the GIL, which is why PyErr does not implement Clone. /// Clone the PyErr. This requires the GIL, which is why PyErr does not implement Clone.

View file

@ -202,8 +202,9 @@ fn initialize_tp_dict(
// We hold the GIL: the dictionary update can be considered atomic from // We hold the GIL: the dictionary update can be considered atomic from
// the POV of other threads. // the POV of other threads.
for (key, val) in items { for (key, val) in items {
let ret = unsafe { ffi::PyObject_SetAttrString(type_object, key.as_ptr(), val.into_ptr()) }; crate::err::error_on_minusone(py, unsafe {
crate::err::error_on_minusone(py, ret)?; ffi::PyObject_SetAttrString(type_object, key.as_ptr(), val.into_ptr())
})?;
} }
Ok(()) Ok(())
} }

View file

@ -650,12 +650,9 @@ impl<T> Py<T> {
let attr_name = attr_name.into_py(py); let attr_name = attr_name.into_py(py);
let value = value.into_py(py); let value = value.into_py(py);
unsafe { err::error_on_minusone(py, unsafe {
err::error_on_minusone( ffi::PyObject_SetAttr(self.as_ptr(), attr_name.as_ptr(), value.as_ptr())
py, })
ffi::PyObject_SetAttr(self.as_ptr(), attr_name.as_ptr(), value.as_ptr()),
)
}
} }
/// Calls the object. /// Calls the object.

View file

@ -876,8 +876,7 @@ impl<'py> Python<'py> {
/// [1]: https://docs.python.org/3/c-api/exceptions.html?highlight=pyerr_checksignals#c.PyErr_CheckSignals /// [1]: https://docs.python.org/3/c-api/exceptions.html?highlight=pyerr_checksignals#c.PyErr_CheckSignals
/// [2]: https://docs.python.org/3/library/signal.html /// [2]: https://docs.python.org/3/library/signal.html
pub fn check_signals(self) -> PyResult<()> { pub fn check_signals(self) -> PyResult<()> {
let v = unsafe { ffi::PyErr_CheckSignals() }; err::error_on_minusone(self, unsafe { ffi::PyErr_CheckSignals() })
err::error_on_minusone(self, v)
} }
/// Create a new pool for managing PyO3's owned references. /// Create a new pool for managing PyO3's owned references.

View file

@ -227,14 +227,14 @@ impl PyAny {
N: IntoPy<Py<PyString>>, N: IntoPy<Py<PyString>>,
V: ToPyObject, V: ToPyObject,
{ {
let py = self.py(); fn inner(any: &PyAny, attr_name: Py<PyString>, value: PyObject) -> PyResult<()> {
let attr_name = attr_name.into_py(py); err::error_on_minusone(any.py(), unsafe {
let value = value.to_object(py); ffi::PyObject_SetAttr(any.as_ptr(), attr_name.as_ptr(), value.as_ptr())
})
unsafe {
let ret = ffi::PyObject_SetAttr(self.as_ptr(), attr_name.as_ptr(), value.as_ptr());
err::error_on_minusone(py, ret)
} }
let py = self.py();
inner(self, attr_name.into_py(py), value.to_object(py))
} }
/// Deletes an attribute. /// Deletes an attribute.
@ -247,13 +247,13 @@ impl PyAny {
where where
N: IntoPy<Py<PyString>>, N: IntoPy<Py<PyString>>,
{ {
let py = self.py(); fn inner(any: &PyAny, attr_name: Py<PyString>) -> PyResult<()> {
let attr_name = attr_name.into_py(py); err::error_on_minusone(any.py(), unsafe {
ffi::PyObject_DelAttr(any.as_ptr(), attr_name.as_ptr())
unsafe { })
let ret = ffi::PyObject_DelAttr(self.as_ptr(), attr_name.as_ptr());
err::error_on_minusone(py, ret)
} }
inner(self, attr_name.into_py(self.py()))
} }
/// Returns an [`Ordering`] between `self` and `other`. /// Returns an [`Ordering`] between `self` and `other`.

View file

@ -68,15 +68,12 @@ impl PyDict {
/// this keeps the last entry seen. /// this keeps the last entry seen.
#[cfg(not(PyPy))] #[cfg(not(PyPy))]
pub fn from_sequence(py: Python<'_>, seq: PyObject) -> PyResult<&PyDict> { pub fn from_sequence(py: Python<'_>, seq: PyObject) -> PyResult<&PyDict> {
unsafe { let dict = Self::new(py);
let dict = py.from_owned_ptr::<PyDict>(ffi::PyDict_New()); err::error_on_minusone(py, unsafe {
err::error_on_minusone( ffi::PyDict_MergeFromSeq2(dict.into_ptr(), seq.into_ptr(), 1)
py, })?;
ffi::PyDict_MergeFromSeq2(dict.into_ptr(), seq.into_ptr(), 1),
)?;
Ok(dict) Ok(dict)
} }
}
/// Returns a new dictionary that contains the same key-value pairs as self. /// Returns a new dictionary that contains the same key-value pairs as self.
/// ///
@ -273,7 +270,9 @@ impl PyDict {
/// to use `self.update(other.as_mapping())`, note: `PyDict::as_mapping` is a zero-cost conversion. /// to use `self.update(other.as_mapping())`, note: `PyDict::as_mapping` is a zero-cost conversion.
pub fn update(&self, other: &PyMapping) -> PyResult<()> { pub fn update(&self, other: &PyMapping) -> PyResult<()> {
let py = self.py(); let py = self.py();
unsafe { err::error_on_minusone(py, ffi::PyDict_Update(self.as_ptr(), other.as_ptr())) } err::error_on_minusone(py, unsafe {
ffi::PyDict_Update(self.as_ptr(), other.as_ptr())
})
} }
/// Add key/value pairs from another dictionary to this one only when they do not exist in this. /// Add key/value pairs from another dictionary to this one only when they do not exist in this.
@ -286,7 +285,9 @@ impl PyDict {
/// so should have the same performance as `update`. /// so should have the same performance as `update`.
pub fn update_if_missing(&self, other: &PyMapping) -> PyResult<()> { pub fn update_if_missing(&self, other: &PyMapping) -> PyResult<()> {
let py = self.py(); let py = self.py();
unsafe { err::error_on_minusone(py, ffi::PyDict_Merge(self.as_ptr(), other.as_ptr(), 0)) } err::error_on_minusone(py, unsafe {
ffi::PyDict_Merge(self.as_ptr(), other.as_ptr(), 0)
})
} }
} }

View file

@ -213,9 +213,7 @@ pub(crate) fn new_from_iter<T: ToPyObject>(
let ptr = set.as_ptr(); let ptr = set.as_ptr();
for obj in elements { for obj in elements {
unsafe { err::error_on_minusone(py, unsafe { ffi::PySet_Add(ptr, obj.as_ptr()) })?;
err::error_on_minusone(py, ffi::PySet_Add(ptr, obj.as_ptr()))?;
}
} }
Ok(set) Ok(set)

View file

@ -167,16 +167,13 @@ impl PyList {
where where
I: ToPyObject, I: ToPyObject,
{ {
unsafe { fn inner(list: &PyList, index: usize, item: PyObject) -> PyResult<()> {
err::error_on_minusone( err::error_on_minusone(list.py(), unsafe {
self.py(), ffi::PyList_SetItem(list.as_ptr(), get_ssize_index(index), item.into_ptr())
ffi::PyList_SetItem( })
self.as_ptr(),
get_ssize_index(index),
item.to_object(self.py()).into_ptr(),
),
)
} }
inner(self, index, item.to_object(self.py()))
} }
/// Deletes the `index`th element of self. /// Deletes the `index`th element of self.
@ -192,17 +189,14 @@ impl PyList {
/// This is equivalent to the Python statement `self[low:high] = v`. /// This is equivalent to the Python statement `self[low:high] = v`.
#[inline] #[inline]
pub fn set_slice(&self, low: usize, high: usize, seq: &PyAny) -> PyResult<()> { pub fn set_slice(&self, low: usize, high: usize, seq: &PyAny) -> PyResult<()> {
unsafe { err::error_on_minusone(self.py(), unsafe {
err::error_on_minusone(
self.py(),
ffi::PyList_SetSlice( ffi::PyList_SetSlice(
self.as_ptr(), self.as_ptr(),
get_ssize_index(low), get_ssize_index(low),
get_ssize_index(high), get_ssize_index(high),
seq.as_ptr(), seq.as_ptr(),
),
) )
} })
} }
/// Deletes the slice from `low` to `high` from `self`. /// Deletes the slice from `low` to `high` from `self`.
@ -275,12 +269,12 @@ impl PyList {
/// Sorts the list in-place. Equivalent to the Python expression `l.sort()`. /// Sorts the list in-place. Equivalent to the Python expression `l.sort()`.
pub fn sort(&self) -> PyResult<()> { pub fn sort(&self) -> PyResult<()> {
unsafe { err::error_on_minusone(self.py(), ffi::PyList_Sort(self.as_ptr())) } err::error_on_minusone(self.py(), unsafe { ffi::PyList_Sort(self.as_ptr()) })
} }
/// Reverses the list in-place. Equivalent to the Python expression `l.reverse()`. /// Reverses the list in-place. Equivalent to the Python expression `l.reverse()`.
pub fn reverse(&self) -> PyResult<()> { pub fn reverse(&self) -> PyResult<()> {
unsafe { err::error_on_minusone(self.py(), ffi::PyList_Reverse(self.as_ptr())) } err::error_on_minusone(self.py(), unsafe { ffi::PyList_Reverse(self.as_ptr()) })
} }
/// Return a new tuple containing the contents of the list; equivalent to the Python expression `tuple(list)`. /// Return a new tuple containing the contents of the list; equivalent to the Python expression `tuple(list)`.

View file

@ -1,4 +1,4 @@
use crate::err::{PyDowncastError, PyErr, PyResult}; use crate::err::{PyDowncastError, PyResult};
use crate::sync::GILOnceCell; use crate::sync::GILOnceCell;
use crate::type_object::PyTypeInfo; use crate::type_object::PyTypeInfo;
use crate::types::{PyAny, PyDict, PySequence, PyType}; use crate::types::{PyAny, PyDict, PySequence, PyType};

View file

@ -139,12 +139,9 @@ impl PySequence {
/// This is equivalent to the Python statement `del self[i]`. /// This is equivalent to the Python statement `del self[i]`.
#[inline] #[inline]
pub fn del_item(&self, i: usize) -> PyResult<()> { pub fn del_item(&self, i: usize) -> PyResult<()> {
unsafe { err::error_on_minusone(self.py(), unsafe {
err::error_on_minusone( ffi::PySequence_DelItem(self.as_ptr(), get_ssize_index(i))
self.py(), })
ffi::PySequence_DelItem(self.as_ptr(), get_ssize_index(i)),
)
}
} }
/// Assigns the sequence `v` to the slice of `self` from `i1` to `i2`. /// Assigns the sequence `v` to the slice of `self` from `i1` to `i2`.
@ -152,17 +149,14 @@ impl PySequence {
/// This is equivalent to the Python statement `self[i1:i2] = v`. /// This is equivalent to the Python statement `self[i1:i2] = v`.
#[inline] #[inline]
pub fn set_slice(&self, i1: usize, i2: usize, v: &PyAny) -> PyResult<()> { pub fn set_slice(&self, i1: usize, i2: usize, v: &PyAny) -> PyResult<()> {
unsafe { err::error_on_minusone(self.py(), unsafe {
err::error_on_minusone(
self.py(),
ffi::PySequence_SetSlice( ffi::PySequence_SetSlice(
self.as_ptr(), self.as_ptr(),
get_ssize_index(i1), get_ssize_index(i1),
get_ssize_index(i2), get_ssize_index(i2),
v.as_ptr(), v.as_ptr(),
),
) )
} })
} }
/// Deletes the slice from `i1` to `i2` from `self`. /// Deletes the slice from `i1` to `i2` from `self`.
@ -170,12 +164,9 @@ impl PySequence {
/// This is equivalent to the Python statement `del self[i1:i2]`. /// This is equivalent to the Python statement `del self[i1:i2]`.
#[inline] #[inline]
pub fn del_slice(&self, i1: usize, i2: usize) -> PyResult<()> { pub fn del_slice(&self, i1: usize, i2: usize) -> PyResult<()> {
unsafe { err::error_on_minusone(self.py(), unsafe {
err::error_on_minusone( ffi::PySequence_DelSlice(self.as_ptr(), get_ssize_index(i1), get_ssize_index(i2))
self.py(), })
ffi::PySequence_DelSlice(self.as_ptr(), get_ssize_index(i1), get_ssize_index(i2)),
)
}
} }
/// Returns the number of occurrences of `value` in self, that is, return the /// Returns the number of occurrences of `value` in self, that is, return the

View file

@ -257,9 +257,7 @@ pub(crate) fn new_from_iter<T: ToPyObject>(
let ptr = set.as_ptr(); let ptr = set.as_ptr();
for obj in elements { for obj in elements {
unsafe { err::error_on_minusone(py, unsafe { ffi::PySet_Add(ptr, obj.as_ptr()) })?;
err::error_on_minusone(py, ffi::PySet_Add(ptr, obj.as_ptr()))?;
}
} }
Ok(set) Ok(set)