@@ -36,19 +36,24 @@ pub fn parse_fn_args<'p>(
36
36
py : Python < ' p > ,
37
37
fname : Option < & str > ,
38
38
params : & [ ParamDescription ] ,
39
- args : & mut & ' p PyTuple ,
40
- kwargs : & mut Option < & ' p PyDict > ,
39
+ args : & ' p PyTuple ,
40
+ kwargs : Option < & ' p PyDict > ,
41
41
accept_args : bool ,
42
42
accept_kwargs : bool ,
43
43
output : & mut [ Option < & ' p PyAny > ] ,
44
- ) -> PyResult < ( ) > {
44
+ ) -> PyResult < ( & ' p PyTuple , Option < & ' p PyDict > ) > {
45
45
let nargs = args. len ( ) ;
46
46
let mut used_args = 0 ;
47
47
macro_rules! raise_error {
48
48
( $s: expr $( , $arg: expr) * ) => ( return Err ( TypeError :: py_err( format!(
49
49
concat!( "{} " , $s) , fname. unwrap_or( "function" ) $( , $arg) *
50
50
) ) ) )
51
51
}
52
+ // Copy kwargs not to modify it
53
+ let kwargs = match kwargs {
54
+ Some ( k) => Some ( k. copy ( ) ?) ,
55
+ None => None ,
56
+ } ;
52
57
// Iterate through the parameters and assign values to output:
53
58
for ( i, ( p, out) ) in params. iter ( ) . zip ( output) . enumerate ( ) {
54
59
* out = match kwargs. and_then ( |d| d. get_item ( p. name ) ) {
@@ -93,16 +98,18 @@ pub fn parse_fn_args<'p>(
93
98
)
94
99
}
95
100
// Adjust the remaining args
96
- if accept_args {
97
- let slice = args
98
- . slice ( used_args as isize , nargs as isize )
99
- . into_object ( py) ;
100
- * args = py. checked_cast_as ( slice) . unwrap ( ) ;
101
- }
102
- if accept_kwargs && is_kwargs_empty {
103
- * kwargs = None ;
104
- }
105
- Ok ( ( ) )
101
+ let args = if accept_args {
102
+ let slice = args. slice ( used_args as isize , nargs as isize ) . into_py ( py) ;
103
+ py. checked_cast_as ( slice) . unwrap ( )
104
+ } else {
105
+ args
106
+ } ;
107
+ let kwargs = if accept_kwargs && is_kwargs_empty {
108
+ None
109
+ } else {
110
+ kwargs
111
+ } ;
112
+ Ok ( ( args, kwargs) )
106
113
}
107
114
108
115
/// Builds a module (or null) from a user given initializer. Used for `#[pymodule]`.
0 commit comments