Change exception print to work with traceback object

This commit is contained in:
Aviv Palivoda
2019-10-26 20:43:36 +03:00
parent b41f871151
commit c0bade2535
2 changed files with 23 additions and 52 deletions

View File

@@ -1,5 +1,5 @@
use crate::function::PyFuncArgs;
use crate::obj::objsequence;
use crate::obj::objtraceback::PyTracebackRef;
use crate::obj::objtuple::{PyTuple, PyTupleRef};
use crate::obj::objtype;
use crate::obj::objtype::PyClassRef;
@@ -83,44 +83,15 @@ fn print_source_line<W: Write>(mut output: W, filename: &str, lineno: usize) ->
}
/// Print exception occurrence location from traceback element
fn print_traceback_entry<W: Write>(
mut output: W,
vm: &VirtualMachine,
tb_entry: &PyObjectRef,
) -> io::Result<()> {
if objtype::isinstance(&tb_entry, &vm.ctx.tuple_type()) {
let location_attrs = objsequence::get_elements_tuple(&tb_entry);
fn print_traceback_entry<W: Write>(mut output: W, tb_entry: &PyTracebackRef) -> io::Result<()> {
let filename = tb_entry.frame.code.source_path.to_string();
writeln!(
output,
r##" File "{}", line {}, in {}"##,
filename, tb_entry.lineno, tb_entry.frame.code.obj_name
)?;
print_source_line(output, &filename, tb_entry.lineno)?;
let filename = vm.to_str(&location_attrs[0]);
let filename = if let Ok(ref x) = filename {
x.as_str()
} else {
"<error>"
};
let lineno = vm.to_str(&location_attrs[1]);
let lineno = if let Ok(ref x) = lineno {
x.as_str()
} else {
"<error>"
};
let obj_name = vm.to_str(&location_attrs[2]);
let obj_name = if let Ok(ref x) = obj_name {
x.as_str()
} else {
"<error>"
};
writeln!(
output,
r##" File "{}", line {}, in {}"##,
filename, lineno, obj_name
)?;
print_source_line(output, filename, lineno.parse().unwrap())?;
} else {
writeln!(output, " File ??")?;
}
Ok(())
}
@@ -131,15 +102,15 @@ pub fn print_exception_inner<W: Write>(
exc: &PyObjectRef,
) -> io::Result<()> {
if let Ok(tb) = vm.get_attribute(exc.clone(), "__traceback__") {
if objtype::isinstance(&tb, &vm.ctx.list_type()) {
let mut tb_entries = objsequence::get_elements_list(&tb).to_vec();
tb_entries.reverse();
if !tb_entries.is_empty() {
writeln!(output, "Traceback (most recent call last):")?;
}
for exc_location in tb_entries.iter() {
print_traceback_entry(&mut output, vm, exc_location)?;
if objtype::isinstance(&tb, &vm.ctx.traceback_type()) {
writeln!(output, "Traceback (most recent call last):")?;
let mut tb: PyTracebackRef = tb.downcast().expect(" must be a traceback object");
loop {
print_traceback_entry(&mut output, &tb)?;
tb = match &tb.next {
Some(tb) => tb.clone(),
None => break,
};
}
}
} else {

View File

@@ -6,13 +6,13 @@ use crate::vm::VirtualMachine;
#[pyclass]
#[derive(Debug)]
pub struct PyTraceback {
next: Option<PyTracebackRef>,
frame: FrameRef,
lasti: usize,
lineno: usize,
pub next: Option<PyTracebackRef>,
pub frame: FrameRef,
pub lasti: usize,
pub lineno: usize,
}
type PyTracebackRef = PyRef<PyTraceback>;
pub type PyTracebackRef = PyRef<PyTraceback>;
impl PyValue for PyTraceback {
fn class(vm: &VirtualMachine) -> PyClassRef {