Skip to content

Commit 6127c08

Browse files
committed
Unraiseable exc
1 parent aef4de4 commit 6127c08

1 file changed

Lines changed: 39 additions & 9 deletions

File tree

crates/vm/src/stdlib/sys.rs

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ mod sys {
1515
},
1616
convert::ToPyObject,
1717
frame::FrameRef,
18-
function::{FuncArgs, OptionalArg, PosArgs},
18+
function::{FuncArgs, KwArgs, OptionalArg, PosArgs},
1919
stdlib::{builtins, warnings::warn},
2020
types::PyStructSequence,
2121
version,
@@ -688,32 +688,62 @@ mod sys {
688688
writeln!(stderr, "{}:", unraisable.err_msg.str(vm)?);
689689
}
690690

691-
// TODO: print received unraisable.exc_traceback
692-
let tb_module = vm.import("traceback", 0)?;
693-
let print_stack = tb_module.get_attr("print_stack", vm)?;
694-
print_stack.call((), vm)?;
691+
// Print traceback (using actual exc_traceback, not current stack)
692+
if !vm.is_none(&unraisable.exc_traceback) {
693+
let tb_module = vm.import("traceback", 0)?;
694+
let print_tb = tb_module.get_attr("print_tb", vm)?;
695+
let stderr_obj = super::get_stderr(vm)?;
696+
let kwargs: KwArgs = [("file".to_string(), stderr_obj)].into_iter().collect();
697+
let _ = print_tb.call(
698+
FuncArgs::new(vec![unraisable.exc_traceback.clone()], kwargs),
699+
vm,
700+
);
701+
}
695702

703+
// Check exc_type
696704
if vm.is_none(unraisable.exc_type.as_object()) {
697-
// TODO: early return, but with what error?
705+
return Ok(());
698706
}
699707
assert!(
700708
unraisable
701709
.exc_type
702710
.fast_issubclass(vm.ctx.exceptions.base_exception_type)
703711
);
704712

705-
// TODO: print module name and qualname
713+
// Print module name (if not builtins or __main__)
714+
let module_name = unraisable.exc_type.__module__(vm);
715+
if let Ok(module_str) = module_name.downcast::<PyStr>() {
716+
let module = module_str.as_str();
717+
if module != "builtins" && module != "__main__" {
718+
write!(stderr, "{}.", module);
719+
}
720+
}
721+
722+
// Print qualname
723+
let qualname = unraisable.exc_type.__qualname__(vm);
724+
if let Ok(qualname_str) = qualname.downcast::<PyStr>() {
725+
write!(stderr, "{}", qualname_str.as_str());
726+
} else {
727+
write!(stderr, "{}", unraisable.exc_type.name());
728+
}
706729

730+
// Print exception value
707731
if !vm.is_none(&unraisable.exc_value) {
708-
write!(stderr, "{}: ", unraisable.exc_type);
732+
write!(stderr, ": ");
709733
if let Ok(str) = unraisable.exc_value.str(vm) {
710734
write!(stderr, "{}", str.to_str().unwrap_or("<str with surrogate>"));
711735
} else {
712736
write!(stderr, "<exception str() failed>");
713737
}
714738
}
715739
writeln!(stderr);
716-
// TODO: call file.flush()
740+
741+
// Flush stderr
742+
if let Ok(stderr_obj) = super::get_stderr(vm)
743+
&& let Ok(flush) = stderr_obj.get_attr("flush", vm)
744+
{
745+
let _ = flush.call((), vm);
746+
}
717747

718748
Ok(())
719749
}

0 commit comments

Comments
 (0)