mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-02 19:39:49 +09:00
Change exception print to work with traceback object
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user