Parse argument list fname: Name of the current function params: Declared parameters of the function args: Positional arguments kwargs: Keyword arguments output: Output array that receives the arguments. Must have same length as `params` and must be initialized to `None`.
(
py: Python,
fname: Option<&str>,
params: &[ParamDescription],
args: &PyTuple,
kwargs: Option<&PyDict>,
output: &mut [Option<PyObject>],
)
| 51 | /// * output: Output array that receives the arguments. |
| 52 | /// Must have same length as `params` and must be initialized to `None`. |
| 53 | pub fn parse_args( |
| 54 | py: Python, |
| 55 | fname: Option<&str>, |
| 56 | params: &[ParamDescription], |
| 57 | args: &PyTuple, |
| 58 | kwargs: Option<&PyDict>, |
| 59 | output: &mut [Option<PyObject>], |
| 60 | ) -> PyResult<()> { |
| 61 | assert!(params.len() == output.len()); |
| 62 | let nargs = args.len(py); |
| 63 | let nkeywords = kwargs.map_or(0, |d| d.len(py)); |
| 64 | if nargs + nkeywords > params.len() { |
| 65 | return Err(err::PyErr::new::<exc::TypeError, _>( |
| 66 | py, |
| 67 | format!( |
| 68 | "{}{} takes at most {} argument{} ({} given)", |
| 69 | fname.unwrap_or("function"), |
| 70 | if fname.is_some() { "()" } else { "" }, |
| 71 | params.len(), |
| 72 | if params.len() != 1 { "s" } else { "" }, |
| 73 | nargs + nkeywords |
| 74 | ), |
| 75 | )); |
| 76 | } |
| 77 | let mut used_keywords = 0; |
| 78 | // Iterate through the parameters and assign values to output: |
| 79 | for (i, (p, out)) in params.iter().zip(output).enumerate() { |
| 80 | match kwargs.and_then(|d| d.get_item(py, p.name())) { |
| 81 | Some(kwarg) => { |
| 82 | *out = Some(kwarg); |
| 83 | used_keywords += 1; |
| 84 | if i < nargs { |
| 85 | return Err(err::PyErr::new::<exc::TypeError, _>( |
| 86 | py, |
| 87 | format!( |
| 88 | "Argument given by name ('{}') and position ({})", |
| 89 | p.name(), |
| 90 | i + 1 |
| 91 | ), |
| 92 | )); |
| 93 | } |
| 94 | } |
| 95 | None => { |
| 96 | if i < nargs { |
| 97 | *out = Some(args.get_item(py, i)); |
| 98 | } else { |
| 99 | *out = None; |
| 100 | if !p.is_optional { |
| 101 | return Err(err::PyErr::new::<exc::TypeError, _>( |
| 102 | py, |
| 103 | format!( |
| 104 | "Required argument ('{}') (pos {}) not found", |
| 105 | p.name(), |
| 106 | i + 1 |
| 107 | ), |
| 108 | )); |
| 109 | } |
| 110 | } |