|
1 | 1 | //! Implementation of the _thread module |
2 | 2 | #[cfg_attr(target_arch = "wasm32", allow(unused_imports))] |
3 | | -pub(crate) use _thread::{ |
| 3 | +pub(crate) use self::_thread::{ |
4 | 4 | CurrentFrameSlot, HandleEntry, RawRMutex, ShutdownEntry, after_fork_child, |
5 | 5 | get_all_current_frames, get_ident, init_main_thread_ident, make_module, |
6 | 6 | }; |
@@ -759,136 +759,7 @@ pub(crate) mod _thread { |
759 | 759 | Ok(()) |
760 | 760 | } |
761 | 761 |
|
762 | | ->>>>>>> 884966677 (gc) |
763 | | - #[pyattr] |
764 | | - #[pyclass(module = "_thread", name = "_ExceptHookArgs")] |
765 | | - #[derive(Debug, PyPayload)] |
766 | | - struct ExceptHookArgs { |
767 | | - exc_type: crate::PyObjectRef, |
768 | | - exc_value: crate::PyObjectRef, |
769 | | - exc_traceback: crate::PyObjectRef, |
770 | | - thread: crate::PyObjectRef, |
771 | | - } |
772 | | - |
773 | | - #[pyclass(with(Constructor))] |
774 | | - impl ExceptHookArgs { |
775 | | - #[pygetset] |
776 | | - fn exc_type(&self) -> crate::PyObjectRef { |
777 | | - self.exc_type.clone() |
778 | | - } |
779 | | - |
780 | | - #[pygetset] |
781 | | - fn exc_value(&self) -> crate::PyObjectRef { |
782 | | - self.exc_value.clone() |
783 | | - } |
784 | | - |
785 | | - #[pygetset] |
786 | | - fn exc_traceback(&self) -> crate::PyObjectRef { |
787 | | - self.exc_traceback.clone() |
788 | | - } |
789 | | - |
790 | | - #[pygetset] |
791 | | - fn thread(&self) -> crate::PyObjectRef { |
792 | | - self.thread.clone() |
793 | | - } |
794 | | - } |
795 | | - |
796 | | - impl Constructor for ExceptHookArgs { |
797 | | - // Takes a single iterable argument like namedtuple |
798 | | - type Args = (crate::PyObjectRef,); |
799 | | - |
800 | | - fn py_new(_cls: &Py<PyType>, args: Self::Args, vm: &VirtualMachine) -> PyResult<Self> { |
801 | | - // Convert the argument to a list/tuple and extract elements |
802 | | - let seq: Vec<crate::PyObjectRef> = args.0.try_to_value(vm)?; |
803 | | - if seq.len() != 4 { |
804 | | - return Err(vm.new_type_error(format!( |
805 | | - "_ExceptHookArgs expected 4 arguments, got {}", |
806 | | - seq.len() |
807 | | - ))); |
808 | | - } |
809 | | - Ok(Self { |
810 | | - exc_type: seq[0].clone(), |
811 | | - exc_value: seq[1].clone(), |
812 | | - exc_traceback: seq[2].clone(), |
813 | | - thread: seq[3].clone(), |
814 | | - }) |
815 | | - } |
816 | | - } |
817 | | - |
818 | | - /// Handle uncaught exception in Thread.run() |
819 | | - #[pyfunction] |
820 | | - fn _excepthook(args: crate::PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { |
821 | | - // Type check: args must be _ExceptHookArgs |
822 | | - let args = args.downcast::<ExceptHookArgs>().map_err(|_| { |
823 | | - vm.new_type_error( |
824 | | - "_thread._excepthook argument type must be _ExceptHookArgs".to_owned(), |
825 | | - ) |
826 | | - })?; |
827 | | - |
828 | | - let exc_type = args.exc_type.clone(); |
829 | | - let exc_value = args.exc_value.clone(); |
830 | | - let exc_traceback = args.exc_traceback.clone(); |
831 | | - let thread = args.thread.clone(); |
832 | 762 |
|
833 | | - // Silently ignore SystemExit (identity check) |
834 | | - if exc_type.is(vm.ctx.exceptions.system_exit.as_ref()) { |
835 | | - return Ok(()); |
836 | | - } |
837 | | - |
838 | | - // Get stderr - fall back to thread._stderr if sys.stderr is None |
839 | | - let file = match vm.sys_module.get_attr("stderr", vm) { |
840 | | - Ok(stderr) if !vm.is_none(&stderr) => stderr, |
841 | | - _ => { |
842 | | - if vm.is_none(&thread) { |
843 | | - // do nothing if sys.stderr is None and thread is None |
844 | | - return Ok(()); |
845 | | - } |
846 | | - let thread_stderr = thread.get_attr("_stderr", vm)?; |
847 | | - if vm.is_none(&thread_stderr) { |
848 | | - // do nothing if sys.stderr is None and sys.stderr was None |
849 | | - // when the thread was created |
850 | | - return Ok(()); |
851 | | - } |
852 | | - thread_stderr |
853 | | - } |
854 | | - }; |
855 | | - |
856 | | - // Print "Exception in thread {thread.name}:" |
857 | | - let thread_name = if !vm.is_none(&thread) { |
858 | | - thread |
859 | | - .get_attr("name", vm) |
860 | | - .ok() |
861 | | - .and_then(|n| n.str(vm).ok()) |
862 | | - .map(|s| s.as_str().to_owned()) |
863 | | - } else { |
864 | | - None |
865 | | - }; |
866 | | - let name = thread_name.unwrap_or_else(|| format!("{}", get_ident())); |
867 | | - |
868 | | - let _ = vm.call_method( |
869 | | - &file, |
870 | | - "write", |
871 | | - (format!("Exception in thread {}:\n", name),), |
872 | | - ); |
873 | | - |
874 | | - // Display the traceback |
875 | | - if let Ok(traceback_mod) = vm.import("traceback", 0) |
876 | | - && let Ok(print_exc) = traceback_mod.get_attr("print_exception", vm) |
877 | | - { |
878 | | - use crate::function::KwArgs; |
879 | | - let kwargs: KwArgs = vec![("file".to_owned(), file.clone())] |
880 | | - .into_iter() |
881 | | - .collect(); |
882 | | - let _ = print_exc.call_with_args( |
883 | | - crate::function::FuncArgs::new(vec![exc_type, exc_value, exc_traceback], kwargs), |
884 | | - vm, |
885 | | - ); |
886 | | - } |
887 | | - |
888 | | - // Flush file |
889 | | - let _ = vm.call_method(&file, "flush", ()); |
890 | | - Ok(()) |
891 | | - } |
892 | 763 |
|
893 | 764 | // Thread-local storage for cleanup guards |
894 | 765 | // When a thread terminates, the guard is dropped, which triggers cleanup |
|
0 commit comments