(mut f_args: FuncArgs, vm: &VirtualMachine)
| 482 | |
| 483 | #[pyfunction] |
| 484 | fn start_new_thread(mut f_args: FuncArgs, vm: &VirtualMachine) -> PyResult<u64> { |
| 485 | if !f_args.kwargs.is_empty() { |
| 486 | return Err(vm.new_type_error("start_new_thread() takes no keyword arguments")); |
| 487 | } |
| 488 | let given = f_args.args.len(); |
| 489 | if given < 2 { |
| 490 | return Err(vm.new_type_error(format!( |
| 491 | "start_new_thread expected at least 2 arguments, got {given}" |
| 492 | ))); |
| 493 | } |
| 494 | if given > 3 { |
| 495 | return Err(vm.new_type_error(format!( |
| 496 | "start_new_thread expected at most 3 arguments, got {given}" |
| 497 | ))); |
| 498 | } |
| 499 | |
| 500 | let func_obj = f_args.take_positional().unwrap(); |
| 501 | let args_obj = f_args.take_positional().unwrap(); |
| 502 | let kwargs_obj = f_args.take_positional(); |
| 503 | |
| 504 | if func_obj.to_callable().is_none() { |
| 505 | return Err(vm.new_type_error("first arg must be callable")); |
| 506 | } |
| 507 | if !args_obj.fast_isinstance(vm.ctx.types.tuple_type) { |
| 508 | return Err(vm.new_type_error("2nd arg must be a tuple")); |
| 509 | } |
| 510 | if kwargs_obj |
| 511 | .as_ref() |
| 512 | .is_some_and(|obj| !obj.fast_isinstance(vm.ctx.types.dict_type)) |
| 513 | { |
| 514 | return Err(vm.new_type_error("optional 3rd arg must be a dictionary")); |
| 515 | } |
| 516 | |
| 517 | let func: ArgCallable = func_obj.clone().try_into_value(vm)?; |
| 518 | let args: PyTupleRef = args_obj.clone().try_into_value(vm)?; |
| 519 | let kwargs: Option<PyDictRef> = kwargs_obj.map(|obj| obj.try_into_value(vm)).transpose()?; |
| 520 | |
| 521 | vm.sys_module.get_attr("audit", vm)?.call( |
| 522 | ( |
| 523 | "_thread.start_new_thread", |
| 524 | func_obj, |
| 525 | args_obj, |
| 526 | kwargs |
| 527 | .as_ref() |
| 528 | .map_or_else(|| vm.ctx.none(), |k| k.clone().into()), |
| 529 | ), |
| 530 | vm, |
| 531 | )?; |
| 532 | |
| 533 | if vm |
| 534 | .state |
| 535 | .finalizing |
| 536 | .load(core::sync::atomic::Ordering::Acquire) |
| 537 | { |
| 538 | return Err(vm.new_exception_msg( |
| 539 | vm.ctx.exceptions.python_finalization_error.to_owned(), |
| 540 | "can't create new thread at interpreter shutdown" |
| 541 | .to_owned() |
nothing calls this directly
no test coverage detected