MCPcopy Index your code
hub / github.com/RustPython/RustPython / fill_locals_from_args

Method fill_locals_from_args

crates/vm/src/builtins/function.rs:222–447  ·  view source on GitHub ↗
(
        &self,
        frame: &Frame,
        func_args: FuncArgs,
        vm: &VirtualMachine,
    )

Source from the content-addressed store, hash-verified

220 }
221
222 fn fill_locals_from_args(
223 &self,
224 frame: &Frame,
225 func_args: FuncArgs,
226 vm: &VirtualMachine,
227 ) -> PyResult<()> {
228 let code: &Py<PyCode> = &self.code;
229 let nargs = func_args.args.len();
230 let n_expected_args = code.arg_count as usize;
231 let total_args = code.arg_count as usize + code.kwonlyarg_count as usize;
232 // let arg_names = self.code.arg_names();
233
234 // This parses the arguments from args and kwargs into
235 // the proper variables keeping into account default values
236 // and star-args and kwargs.
237 // See also: PyEval_EvalCodeWithName in cpython:
238 // https://github.com/python/cpython/blob/main/Python/ceval.c#L3681
239
240 // SAFETY: Frame was just created and not yet executing.
241 let fastlocals = unsafe { frame.fastlocals_mut() };
242
243 let mut args_iter = func_args.args.into_iter();
244
245 // Copy positional arguments into local variables
246 // zip short-circuits if either iterator returns None, which is the behavior we want --
247 // only fill as much as there is to fill with as much as we have
248 for (local, arg) in Iterator::zip(
249 fastlocals.iter_mut().take(n_expected_args),
250 args_iter.by_ref().take(nargs),
251 ) {
252 *local = Some(arg);
253 }
254
255 let mut vararg_offset = total_args;
256 // Pack other positional arguments in to *args:
257 if code.flags.contains(bytecode::CodeFlags::VARARGS) {
258 let vararg_value = vm.ctx.new_tuple(args_iter.collect());
259 fastlocals[vararg_offset] = Some(vararg_value.into());
260 vararg_offset += 1;
261 } else {
262 // Check the number of positional arguments
263 if nargs > n_expected_args {
264 let n_defaults = self
265 .defaults_and_kwdefaults
266 .lock()
267 .0
268 .as_ref()
269 .map_or(0, |d| d.len());
270 let n_required = n_expected_args - n_defaults;
271 let takes_msg = if n_defaults > 0 {
272 format!("from {} to {}", n_required, n_expected_args)
273 } else {
274 n_expected_args.to_string()
275 };
276
277 // Count keyword-only arguments that were actually provided
278 let kw_only_given = if code.kwonlyarg_count > 0 {
279 let start = code.arg_count as usize;

Callers 1

invoke_with_localsMethod · 0.80

Calls 15

newFunction · 0.85
format_missing_argsFunction · 0.85
minFunction · 0.85
fastlocals_mutMethod · 0.80
collectMethod · 0.80
to_stringMethod · 0.80
contains_keyMethod · 0.80
new_dictMethod · 0.80
get_item_optMethod · 0.80
SomeClass · 0.50
ErrClass · 0.50
lenMethod · 0.45

Tested by

no test coverage detected