(&mut self, vm: &VirtualMachine)
| 6450 | } |
| 6451 | |
| 6452 | fn collect_ex_args(&mut self, vm: &VirtualMachine) -> PyResult<FuncArgs> { |
| 6453 | let kwargs_or_null = self.pop_value_opt(); |
| 6454 | let kwargs = if let Some(kw_obj) = kwargs_or_null { |
| 6455 | let mut kwargs = IndexMap::new(); |
| 6456 | |
| 6457 | // Stack: [callable, self_or_null, args_tuple] |
| 6458 | let callable = self.nth_value(2); |
| 6459 | let func_str = Self::object_function_str(callable, vm); |
| 6460 | |
| 6461 | Self::iterate_mapping_keys(vm, &kw_obj, &func_str, |key| { |
| 6462 | let key_str = key |
| 6463 | .downcast_ref::<PyUtf8Str>() |
| 6464 | .ok_or_else(|| vm.new_type_error("keywords must be strings"))?; |
| 6465 | let value = kw_obj.get_item(&*key, vm)?; |
| 6466 | kwargs.insert(key_str.as_str().to_owned(), value); |
| 6467 | Ok(()) |
| 6468 | })?; |
| 6469 | kwargs |
| 6470 | } else { |
| 6471 | IndexMap::new() |
| 6472 | }; |
| 6473 | let args_obj = self.pop_value(); |
| 6474 | let args = if let Some(tuple) = args_obj.downcast_ref::<PyTuple>() { |
| 6475 | tuple.as_slice().to_vec() |
| 6476 | } else { |
| 6477 | // Single *arg passed directly; convert to sequence at runtime. |
| 6478 | // Stack: [callable, self_or_null] |
| 6479 | let callable = self.nth_value(1); |
| 6480 | let func_str = Self::object_function_str(callable, vm); |
| 6481 | let not_iterable = args_obj.class().slots.iter.load().is_none() |
| 6482 | && args_obj |
| 6483 | .get_class_attr(vm.ctx.intern_str("__getitem__")) |
| 6484 | .is_none(); |
| 6485 | args_obj.try_to_value::<Vec<PyObjectRef>>(vm).map_err(|e| { |
| 6486 | if not_iterable && e.class().is(vm.ctx.exceptions.type_error) { |
| 6487 | vm.new_type_error(format!( |
| 6488 | "{} argument after * must be an iterable, not {}", |
| 6489 | func_str, |
| 6490 | args_obj.class().name() |
| 6491 | )) |
| 6492 | } else { |
| 6493 | e |
| 6494 | } |
| 6495 | })? |
| 6496 | }; |
| 6497 | Ok(FuncArgs { args, kwargs }) |
| 6498 | } |
| 6499 | |
| 6500 | /// Returns a display string for a callable object for use in error messages. |
| 6501 | /// For objects with `__qualname__`, returns "module.qualname()" or "qualname()". |
no test coverage detected