mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
Add traceback object
This commit is contained in:
1 parent
a828249fc0
commit
a9c2f5f711
8 files changed
+96
-17
No files matched your search
@@ -16,7 +16,7 @@ fn exception_init(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
vm.set_attr(&exc_self, "args", exc_args)?;
|
||||
|
||||
// TODO: have an actual `traceback` object for __traceback__
|
||||
vm.set_attr(&exc_self, "__traceback__", vm.ctx.new_list(vec![]))?;
|
||||
vm.set_attr(&exc_self, "__traceback__", vm.get_none())?;
|
||||
vm.set_attr(&exc_self, "__cause__", vm.get_none())?;
|
||||
vm.set_attr(&exc_self, "__context__", vm.get_none())?;
|
||||
vm.set_attr(&exc_self, "__suppress_context__", vm.new_bool(false))?;
|
||||
|
||||
+14
-13
@@ -14,6 +14,7 @@ use crate::obj::objlist;
|
||||
use crate::obj::objslice::PySlice;
|
||||
use crate::obj::objstr;
|
||||
use crate::obj::objstr::PyString;
|
||||
use crate::obj::objtraceback::PyTraceback;
|
||||
use crate::obj::objtuple::PyTuple;
|
||||
use crate::obj::objtype;
|
||||
use crate::obj::objtype::PyClassRef;
|
||||
@@ -80,6 +81,7 @@ enum UnwindReason {
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
#[derive(Clone)]
|
||||
pub struct Frame {
|
||||
pub code: PyCodeRef,
|
||||
// We need 1 stack per frame
|
||||
@@ -167,12 +169,6 @@ impl Frame {
|
||||
// #[cfg_attr(feature = "flame-it", flame("Frame"))]
|
||||
pub fn run(&self, vm: &VirtualMachine) -> PyResult<ExecutionResult> {
|
||||
flame_guard!(format!("Frame::run({})", self.code.obj_name));
|
||||
|
||||
let filename = &self.code.source_path.to_string();
|
||||
|
||||
// This is the name of the object being run:
|
||||
let run_obj_name = &self.code.obj_name.to_string();
|
||||
|
||||
// Execute until return or exception:
|
||||
loop {
|
||||
let lineno = self.get_lineno();
|
||||
@@ -191,16 +187,21 @@ impl Frame {
|
||||
&exception,
|
||||
&vm.ctx.exceptions.base_exception_type
|
||||
));
|
||||
|
||||
let traceback = vm
|
||||
.get_attribute(exception.clone(), "__traceback__")
|
||||
.unwrap();
|
||||
vm_trace!("Adding to traceback: {:?} {:?}", traceback, lineno);
|
||||
let raise_location = vm.ctx.new_tuple(vec![
|
||||
vm.ctx.new_str(filename.clone()),
|
||||
vm.ctx.new_int(lineno.row()),
|
||||
vm.ctx.new_str(run_obj_name.clone()),
|
||||
]);
|
||||
objlist::PyListRef::try_from_object(vm, traceback)?.append(raise_location, vm);
|
||||
let new_traceback = PyTraceback::new(
|
||||
traceback,
|
||||
self.clone().into_ref(vm),
|
||||
self.lasti.get(),
|
||||
lineno.row(),
|
||||
vm,
|
||||
);
|
||||
vm.set_attr(&exception, "__traceback__", new_traceback.into_ref(vm))
|
||||
.unwrap();
|
||||
vm_trace!("Adding to traceback: {:?} {:?}", new_traceback, lineno);
|
||||
|
||||
match self.unwind_blocks(vm, UnwindReason::Raising { exception }) {
|
||||
Ok(None) => {}
|
||||
Ok(Some(result)) => {
|
||||
|
||||
@@ -66,7 +66,6 @@ pub mod pyobject;
|
||||
pub mod scope;
|
||||
pub mod stdlib;
|
||||
mod sysmodule;
|
||||
mod traceback;
|
||||
pub mod types;
|
||||
pub mod util;
|
||||
mod version;
|
||||
|
||||
@@ -34,6 +34,7 @@ pub mod objslice;
|
||||
pub mod objstaticmethod;
|
||||
pub mod objstr;
|
||||
pub mod objsuper;
|
||||
pub mod objtraceback;
|
||||
pub mod objtuple;
|
||||
pub mod objtype;
|
||||
pub mod objweakproxy;
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
use crate::frame::FrameRef;
|
||||
use crate::obj::objtype::PyClassRef;
|
||||
use crate::pyobject::{PyClassImpl, PyContext, PyObjectRef, PyRef, PyValue};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
#[pyclass]
|
||||
#[derive(Debug)]
|
||||
pub struct PyTraceback {
|
||||
next: Option<PyTracebackRef>,
|
||||
frame: FrameRef,
|
||||
lasti: usize,
|
||||
lineno: usize,
|
||||
}
|
||||
|
||||
type PyTracebackRef = PyRef<PyTraceback>;
|
||||
|
||||
impl PyValue for PyTraceback {
|
||||
fn class(vm: &VirtualMachine) -> PyClassRef {
|
||||
vm.ctx.traceback_type()
|
||||
}
|
||||
}
|
||||
|
||||
#[pyimpl]
|
||||
impl PyTraceback {
|
||||
pub fn new(
|
||||
next: PyObjectRef,
|
||||
frame: FrameRef,
|
||||
lasti: usize,
|
||||
lineno: usize,
|
||||
vm: &VirtualMachine,
|
||||
) -> Self {
|
||||
let next = if vm.is_none(&next) {
|
||||
None
|
||||
} else {
|
||||
let traceback: PyTracebackRef =
|
||||
next.downcast().expect("next must be a traceback object");
|
||||
Some(traceback)
|
||||
};
|
||||
|
||||
PyTraceback {
|
||||
next,
|
||||
frame,
|
||||
lasti,
|
||||
lineno,
|
||||
}
|
||||
}
|
||||
|
||||
#[pyproperty(name = "tb_frame")]
|
||||
fn frame(&self, _vm: &VirtualMachine) -> FrameRef {
|
||||
self.frame.clone()
|
||||
}
|
||||
|
||||
#[pyproperty(name = "tb_lasti")]
|
||||
fn lasti(&self, _vm: &VirtualMachine) -> usize {
|
||||
self.lasti
|
||||
}
|
||||
|
||||
#[pyproperty(name = "tb_lineno")]
|
||||
fn lineno(&self, _vm: &VirtualMachine) -> usize {
|
||||
self.lineno
|
||||
}
|
||||
|
||||
#[pyproperty(name = "tb_next")]
|
||||
fn next_get(&self, _vm: &VirtualMachine) -> Option<PyTracebackRef> {
|
||||
self.next.as_ref().map(|x| x.clone())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
PyTraceback::extend_class(context, &context.types.traceback_type);
|
||||
}
|
||||
@@ -349,6 +349,10 @@ impl PyContext {
|
||||
self.types.weakproxy_type.clone()
|
||||
}
|
||||
|
||||
pub fn traceback_type(&self) -> PyClassRef {
|
||||
self.types.traceback_type.clone()
|
||||
}
|
||||
|
||||
pub fn type_type(&self) -> PyClassRef {
|
||||
self.types.type_type.clone()
|
||||
}
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
// python tracebacks
|
||||
//
|
||||
@@ -29,6 +29,7 @@ use crate::obj::objslice;
|
||||
use crate::obj::objstaticmethod;
|
||||
use crate::obj::objstr;
|
||||
use crate::obj::objsuper;
|
||||
use crate::obj::objtraceback;
|
||||
use crate::obj::objtuple;
|
||||
use crate::obj::objtype::{self, PyClass, PyClassRef};
|
||||
use crate::obj::objweakproxy;
|
||||
@@ -93,6 +94,7 @@ pub struct TypeZoo {
|
||||
pub weakref_type: PyClassRef,
|
||||
pub weakproxy_type: PyClassRef,
|
||||
pub mappingproxy_type: PyClassRef,
|
||||
pub traceback_type: PyClassRef,
|
||||
pub object_type: PyClassRef,
|
||||
}
|
||||
|
||||
@@ -158,6 +160,7 @@ impl TypeZoo {
|
||||
let rangeiterator_type = create_type("range_iterator", &type_type, &object_type);
|
||||
let slice_type = create_type("slice", &type_type, &object_type);
|
||||
let mappingproxy_type = create_type("mappingproxy", &type_type, &object_type);
|
||||
let traceback_type = create_type("traceback", &type_type, &object_type);
|
||||
|
||||
Self {
|
||||
bool_type,
|
||||
@@ -212,6 +215,7 @@ impl TypeZoo {
|
||||
weakref_type,
|
||||
weakproxy_type,
|
||||
type_type,
|
||||
traceback_type,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -313,4 +317,5 @@ pub fn initialize_types(context: &PyContext) {
|
||||
objmodule::init(&context);
|
||||
objnamespace::init(&context);
|
||||
objmappingproxy::init(&context);
|
||||
objtraceback::init(&context);
|
||||
}
|
||||
Reference in new issue
Block a user