diff --git a/Lib/test/test_raise.py b/Lib/test/test_raise.py index 94f42c84f1..3ada08f7dc 100644 --- a/Lib/test/test_raise.py +++ b/Lib/test/test_raise.py @@ -270,8 +270,6 @@ def test_attrs(self): tb.tb_next = new_tb self.assertIs(tb.tb_next, new_tb) - # TODO: RUSTPYTHON - @unittest.expectedFailure def test_constructor(self): other_tb = get_tb() frame = sys._getframe() diff --git a/vm/src/builtins/traceback.rs b/vm/src/builtins/traceback.rs index 33063132c6..05e9944e09 100644 --- a/vm/src/builtins/traceback.rs +++ b/vm/src/builtins/traceback.rs @@ -1,8 +1,9 @@ use rustpython_common::lock::PyMutex; -use super::PyType; +use super::{PyType, PyTypeRef}; use crate::{ - Context, Py, PyPayload, PyRef, class::PyClassImpl, frame::FrameRef, source::LineNumber, + Context, Py, PyPayload, PyRef, PyResult, VirtualMachine, class::PyClassImpl, frame::FrameRef, + source::LineNumber, types::Constructor, }; #[pyclass(module = false, name = "traceback", traverse)] @@ -25,7 +26,7 @@ impl PyPayload for PyTraceback { } } -#[pyclass] +#[pyclass(with(Constructor))] impl PyTraceback { pub const fn new( next: Option>, @@ -67,6 +68,18 @@ impl PyTraceback { } } +impl Constructor for PyTraceback { + type Args = (Option>, FrameRef, u32, usize); + + fn py_new(cls: PyTypeRef, args: Self::Args, vm: &VirtualMachine) -> PyResult { + let (next, frame, lasti, lineno) = args; + let lineno = LineNumber::new(lineno) + .ok_or_else(|| vm.new_value_error("lineno must be positive".to_owned()))?; + let tb = PyTraceback::new(next, frame, lasti, lineno); + tb.into_ref_with_type(vm, cls).map(Into::into) + } +} + impl PyTracebackRef { pub fn iter(&self) -> impl Iterator { std::iter::successors(Some(self.clone()), |tb| tb.next.lock().clone())