(args: crate::PyObjectRef, vm: &VirtualMachine)
| 814 | /// Handle uncaught exception in Thread.run() |
| 815 | #[pyfunction] |
| 816 | fn _excepthook(args: crate::PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { |
| 817 | // Type check: args must be _ExceptHookArgs |
| 818 | let args = args.downcast::<ExceptHookArgs>().map_err(|_| { |
| 819 | vm.new_type_error("_thread._excepthook argument type must be _ExceptHookArgs") |
| 820 | })?; |
| 821 | |
| 822 | let exc_type = args.exc_type.clone(); |
| 823 | let exc_value = args.exc_value.clone(); |
| 824 | let exc_traceback = args.exc_traceback.clone(); |
| 825 | let thread = args.thread.clone(); |
| 826 | |
| 827 | // Silently ignore SystemExit (identity check) |
| 828 | if exc_type.is(vm.ctx.exceptions.system_exit.as_ref()) { |
| 829 | return Ok(()); |
| 830 | } |
| 831 | |
| 832 | // Get stderr - fall back to thread._stderr if sys.stderr is None |
| 833 | let file = match vm.sys_module.get_attr("stderr", vm) { |
| 834 | Ok(stderr) if !vm.is_none(&stderr) => stderr, |
| 835 | _ => { |
| 836 | if vm.is_none(&thread) { |
| 837 | // do nothing if sys.stderr is None and thread is None |
| 838 | return Ok(()); |
| 839 | } |
| 840 | let thread_stderr = thread.get_attr("_stderr", vm)?; |
| 841 | if vm.is_none(&thread_stderr) { |
| 842 | // do nothing if sys.stderr is None and sys.stderr was None |
| 843 | // when the thread was created |
| 844 | return Ok(()); |
| 845 | } |
| 846 | thread_stderr |
| 847 | } |
| 848 | }; |
| 849 | |
| 850 | // Print "Exception in thread {thread.name}:" |
| 851 | let thread_name = if !vm.is_none(&thread) { |
| 852 | thread |
| 853 | .get_attr("name", vm) |
| 854 | .ok() |
| 855 | .and_then(|n| n.str(vm).ok()) |
| 856 | .map(|s| s.as_wtf8().to_owned()) |
| 857 | } else { |
| 858 | None |
| 859 | }; |
| 860 | let name = thread_name.unwrap_or_else(|| Wtf8Buf::from(format!("{}", get_ident()))); |
| 861 | |
| 862 | let _ = vm.call_method( |
| 863 | &file, |
| 864 | "write", |
| 865 | (format!("Exception in thread {}:\n", name),), |
| 866 | ); |
| 867 | |
| 868 | // Display the traceback |
| 869 | if let Ok(traceback_mod) = vm.import("traceback", 0) |
| 870 | && let Ok(print_exc) = traceback_mod.get_attr("print_exception", vm) |
| 871 | { |
| 872 | use crate::function::KwArgs; |
| 873 | let kwargs: KwArgs = vec![("file".to_owned(), file.clone())] |
nothing calls this directly
no test coverage detected