Skip to content

Commit 6490983

Browse files
committed
use Borrowed::from_ptr methods in extract_argument
1 parent 22f960f commit 6490983

File tree

3 files changed

+28
-16
lines changed

3 files changed

+28
-16
lines changed

src/impl_/extract_argument.rs

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ where
4848
obj: &'a Bound<'py, PyAny>,
4949
holder: &'a mut Option<&'a Bound<'py, T>>,
5050
) -> PyResult<Self> {
51-
Ok(&*holder.insert(obj.downcast()?))
51+
Ok(holder.insert(obj.downcast()?))
5252
}
5353
}
5454

@@ -261,7 +261,9 @@ impl FunctionDescription {
261261
);
262262

263263
// Handle positional arguments
264-
// Safety: Option<PyArg> has the same memory layout as `*mut ffi::PyObject`
264+
// Safety:
265+
// - Option<PyArg> has the same memory layout as `*mut ffi::PyObject`
266+
// - we both have the GIL and can borrow these input references for the `'py` lifetime.
265267
let args: *const Option<PyArg<'py>> = args.cast();
266268
let positional_args_provided = nargs as usize;
267269
let remaining_positional_args = if args.is_null() {
@@ -284,8 +286,11 @@ impl FunctionDescription {
284286
let mut varkeywords = K::Varkeywords::default();
285287

286288
// Safety: kwnames is known to be a pointer to a tuple, or null
287-
let kwnames: &'py Option<Bound<'py, PyTuple>> = std::mem::transmute(&kwnames);
289+
// - we both have the GIL and can borrow this input reference for the `'py` lifetime.
290+
let kwnames = Borrowed::from_ptr_or_opt(py, kwnames);
288291
if let Some(kwnames) = kwnames.as_ref() {
292+
// Safety: kwnames is known to be a PyTuple from the Python interpreter
293+
let kwnames = kwnames.downcast_unchecked::<PyTuple>();
289294
// Safety: &PyAny has the same memory layout as `*mut ffi::PyObject`
290295
let kwargs = ::std::slice::from_raw_parts(
291296
(args as *const PyArg<'py>).offset(nargs),
@@ -322,7 +327,7 @@ impl FunctionDescription {
322327
/// - `kwargs` must be a pointer to a PyDict, or NULL.
323328
pub unsafe fn extract_arguments_tuple_dict<'py, V, K>(
324329
&self,
325-
_py: Python<'py>,
330+
py: Python<'py>,
326331
args: *mut ffi::PyObject,
327332
kwargs: *mut ffi::PyObject,
328333
output: &mut [Option<PyArg<'py>>],
@@ -331,11 +336,14 @@ impl FunctionDescription {
331336
V: VarargsHandler<'py>,
332337
K: VarkeywordsHandler<'py>,
333338
{
334-
// Safety: Bound has the same layout as a raw pointer, and reference is known to be
335-
// borrowed for 'py.
336-
let args: &'py Bound<'py, PyTuple> = std::mem::transmute(&args);
337-
let kwargs: &'py Option<Bound<'py, PyDict>> = std::mem::transmute(&kwargs);
338-
let kwargs = kwargs.as_ref();
339+
// Safety:
340+
// - `args` is known to be a tuple
341+
// - `kwargs` is known to be a dict or null
342+
// - we both have the GIL and can borrow these input references for the `'py` lifetime.
343+
let args: Borrowed<'py, 'py, PyTuple> =
344+
Borrowed::from_ptr(py, args).downcast_unchecked::<PyTuple>();
345+
let kwargs: Option<Borrowed<'py, 'py, PyDict>> =
346+
Borrowed::from_ptr_or_opt(py, kwargs).map(|kwargs| kwargs.downcast_unchecked());
339347

340348
let num_positional_parameters = self.positional_parameter_names.len();
341349

@@ -356,7 +364,7 @@ impl FunctionDescription {
356364
}
357365

358366
// If any arguments remain, push them to varargs (if possible) or error
359-
let varargs = V::handle_varargs_tuple(args, self)?;
367+
let varargs = V::handle_varargs_tuple(&args, self)?;
360368

361369
// Handle keyword arguments
362370
let mut varkeywords = K::Varkeywords::default();

src/types/dict.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -517,12 +517,12 @@ impl<'py> PyDictMethods<'py> for Bound<'py, PyDict> {
517517
}
518518
}
519519

520-
impl<'py> Bound<'py, PyDict> {
520+
impl<'a, 'py> Borrowed<'a, 'py, PyDict> {
521521
/// Iterates over the contents of this dictionary without incrementing reference counts.
522522
///
523523
/// # Safety
524524
/// It must be known that this dictionary will not be modified during iteration.
525-
pub(crate) unsafe fn iter_borrowed<'a>(&'a self) -> BorrowedDictIter<'a, 'py> {
525+
pub(crate) unsafe fn iter_borrowed(self) -> BorrowedDictIter<'a, 'py> {
526526
BorrowedDictIter::new(self)
527527
}
528528
}
@@ -672,7 +672,7 @@ mod borrowed_iter {
672672
/// without incrementing reference counts. This is only safe if it's known
673673
/// that the dictionary will not be modified during iteration.
674674
pub struct BorrowedDictIter<'a, 'py> {
675-
dict: &'a Bound<'py, PyDict>,
675+
dict: Borrowed<'a, 'py, PyDict>,
676676
ppos: ffi::Py_ssize_t,
677677
len: ffi::Py_ssize_t,
678678
}
@@ -710,8 +710,8 @@ mod borrowed_iter {
710710
}
711711

712712
impl<'a, 'py> BorrowedDictIter<'a, 'py> {
713-
pub(super) fn new(dict: &'a Bound<'py, PyDict>) -> Self {
714-
let len = dict_len(dict);
713+
pub(super) fn new(dict: Borrowed<'a, 'py, PyDict>) -> Self {
714+
let len = dict_len(&dict);
715715
BorrowedDictIter { dict, ppos: 0, len }
716716
}
717717
}

src/types/tuple.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,7 @@ impl<'py> PyTupleMethods<'py> for Bound<'py, PyTuple> {
412412
}
413413

414414
fn iter_borrowed<'a>(&'a self) -> BorrowedTupleIterator<'a, 'py> {
415-
BorrowedTupleIterator::new(self.as_borrowed())
415+
self.as_borrowed().iter_borrowed()
416416
}
417417

418418
fn to_list(&self) -> Bound<'py, PyList> {
@@ -434,6 +434,10 @@ impl<'a, 'py> Borrowed<'a, 'py, PyTuple> {
434434
unsafe fn get_borrowed_item_unchecked(self, index: usize) -> Borrowed<'a, 'py, PyAny> {
435435
ffi::PyTuple_GET_ITEM(self.as_ptr(), index as Py_ssize_t).assume_borrowed(self.py())
436436
}
437+
438+
pub(crate) fn iter_borrowed(self) -> BorrowedTupleIterator<'a, 'py> {
439+
BorrowedTupleIterator::new(self)
440+
}
437441
}
438442

439443
/// Used by `PyTuple::iter()`.

0 commit comments

Comments
 (0)