[derive_utils] Copy kwargs not to modify it

This commit is contained in:
kngwyu 2019-09-01 23:59:24 +09:00
parent 96b71bfb76
commit c7e377a472
2 changed files with 23 additions and 16 deletions

View file

@ -475,12 +475,12 @@ pub fn impl_arg_params(spec: &FnSpec<'_>, body: TokenStream) -> TokenStream {
// Workaround to use the question mark operator without rewriting everything // Workaround to use the question mark operator without rewriting everything
let _result = (|| { let _result = (|| {
pyo3::derive_utils::parse_fn_args( let (_args, _kwargs) = pyo3::derive_utils::parse_fn_args(
_py, _py,
Some(_LOCATION), Some(_LOCATION),
PARAMS, PARAMS,
&mut _args, _args,
&mut _kwargs, _kwargs,
#accept_args, #accept_args,
#accept_kwargs, #accept_kwargs,
&mut output &mut output

View file

@ -36,12 +36,12 @@ pub fn parse_fn_args<'p>(
py: Python<'p>, py: Python<'p>,
fname: Option<&str>, fname: Option<&str>,
params: &[ParamDescription], params: &[ParamDescription],
args: &mut &'p PyTuple, args: &'p PyTuple,
kwargs: &mut Option<&'p PyDict>, kwargs: Option<&'p PyDict>,
accept_args: bool, accept_args: bool,
accept_kwargs: bool, accept_kwargs: bool,
output: &mut [Option<&'p PyAny>], output: &mut [Option<&'p PyAny>],
) -> PyResult<()> { ) -> PyResult<(&'p PyTuple, Option<&'p PyDict>)> {
let nargs = args.len(); let nargs = args.len();
let mut used_args = 0; let mut used_args = 0;
macro_rules! raise_error { macro_rules! raise_error {
@ -49,6 +49,11 @@ pub fn parse_fn_args<'p>(
concat!("{} ", $s), fname.unwrap_or("function") $(,$arg)* concat!("{} ", $s), fname.unwrap_or("function") $(,$arg)*
)))) ))))
} }
// Copy kwargs not to modify it
let kwargs = match kwargs {
Some(k) => Some(k.copy()?),
None => None,
};
// Iterate through the parameters and assign values to output: // Iterate through the parameters and assign values to output:
for (i, (p, out)) in params.iter().zip(output).enumerate() { for (i, (p, out)) in params.iter().zip(output).enumerate() {
*out = match kwargs.and_then(|d| d.get_item(p.name)) { *out = match kwargs.and_then(|d| d.get_item(p.name)) {
@ -93,16 +98,18 @@ pub fn parse_fn_args<'p>(
) )
} }
// Adjust the remaining args // Adjust the remaining args
if accept_args { let args = if accept_args {
let slice = args let slice = args.slice(used_args as isize, nargs as isize).into_py(py);
.slice(used_args as isize, nargs as isize) py.checked_cast_as(slice).unwrap()
.into_object(py); } else {
*args = py.checked_cast_as(slice).unwrap(); args
} };
if accept_kwargs && is_kwargs_empty { let kwargs = if accept_kwargs && is_kwargs_empty {
*kwargs = None; None
} } else {
Ok(()) kwargs
};
Ok((args, kwargs))
} }
/// Builds a module (or null) from a user given initializer. Used for `#[pymodule]`. /// Builds a module (or null) from a user given initializer. Used for `#[pymodule]`.