48
48
obj : & ' a Bound < ' py , PyAny > ,
49
49
holder : & ' a mut Option < & ' a Bound < ' py , T > > ,
50
50
) -> PyResult < Self > {
51
- Ok ( & * holder. insert ( obj. downcast ( ) ?) )
51
+ Ok ( holder. insert ( obj. downcast ( ) ?) )
52
52
}
53
53
}
54
54
@@ -261,7 +261,9 @@ impl FunctionDescription {
261
261
) ;
262
262
263
263
// 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.
265
267
let args: * const Option < PyArg < ' py > > = args. cast ( ) ;
266
268
let positional_args_provided = nargs as usize ;
267
269
let remaining_positional_args = if args. is_null ( ) {
@@ -284,8 +286,11 @@ impl FunctionDescription {
284
286
let mut varkeywords = K :: Varkeywords :: default ( ) ;
285
287
286
288
// 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) ;
288
291
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 > ( ) ;
289
294
// Safety: &PyAny has the same memory layout as `*mut ffi::PyObject`
290
295
let kwargs = :: std:: slice:: from_raw_parts (
291
296
( args as * const PyArg < ' py > ) . offset ( nargs) ,
@@ -322,7 +327,7 @@ impl FunctionDescription {
322
327
/// - `kwargs` must be a pointer to a PyDict, or NULL.
323
328
pub unsafe fn extract_arguments_tuple_dict < ' py , V , K > (
324
329
& self ,
325
- _py : Python < ' py > ,
330
+ py : Python < ' py > ,
326
331
args : * mut ffi:: PyObject ,
327
332
kwargs : * mut ffi:: PyObject ,
328
333
output : & mut [ Option < PyArg < ' py > > ] ,
@@ -331,11 +336,14 @@ impl FunctionDescription {
331
336
V : VarargsHandler < ' py > ,
332
337
K : VarkeywordsHandler < ' py > ,
333
338
{
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 ( ) ) ;
339
347
340
348
let num_positional_parameters = self . positional_parameter_names . len ( ) ;
341
349
@@ -356,7 +364,7 @@ impl FunctionDescription {
356
364
}
357
365
358
366
// 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 ) ?;
360
368
361
369
// Handle keyword arguments
362
370
let mut varkeywords = K :: Varkeywords :: default ( ) ;
0 commit comments