Skip to content

Commit 84003d6

Browse files
committed
Add traceback constructor
1 parent 98f20c4 commit 84003d6

File tree

3 files changed

+29
-8
lines changed

3 files changed

+29
-8
lines changed

Lib/test/test_raise.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,8 +270,6 @@ def test_attrs(self):
270270
tb.tb_next = new_tb
271271
self.assertIs(tb.tb_next, new_tb)
272272

273-
# TODO: RUSTPYTHON
274-
@unittest.expectedFailure
275273
def test_constructor(self):
276274
other_tb = get_tb()
277275
frame = sys._getframe()

vm/src/builtins/traceback.rs

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
use rustpython_common::lock::PyMutex;
22

3+
use crate::types::Constructor;
34
use crate::{Context, PyRef, class::PyClassImpl, frame::FrameRef, source::LineNumber};
5+
use crate::{PyPayload, PyResult, VirtualMachine};
6+
7+
use super::PyTypeRef;
48

59
#[pyclass(module = false, name = "traceback", traverse, ctx = traceback_type)]
610
#[derive(Debug)]
@@ -15,7 +19,26 @@ pub struct PyTraceback {
1519

1620
pub type PyTracebackRef = PyRef<PyTraceback>;
1721

18-
#[pyclass]
22+
impl Constructor for PyTraceback {
23+
type Args = (Option<PyRef<Self>>, FrameRef, u32, usize);
24+
25+
fn py_new(
26+
cls: PyTypeRef,
27+
(next, frame, lasti, lineno): Self::Args,
28+
vm: &VirtualMachine,
29+
) -> PyResult {
30+
Self::new(
31+
next,
32+
frame,
33+
lasti,
34+
LineNumber::new(lineno).unwrap_or(LineNumber::MIN),
35+
)
36+
.into_ref_with_type(vm, cls)
37+
.map(Into::into)
38+
}
39+
}
40+
41+
#[pyclass(with(Constructor))]
1942
impl PyTraceback {
2043
pub fn new(next: Option<PyRef<Self>>, frame: FrameRef, lasti: u32, lineno: LineNumber) -> Self {
2144
PyTraceback {
@@ -42,19 +65,19 @@ impl PyTraceback {
4265
}
4366

4467
#[pygetset]
45-
fn tb_next(&self) -> Option<PyRef<Self>> {
46-
self.next.lock().as_ref().cloned()
68+
pub fn tb_next(&self) -> Option<PyRef<Self>> {
69+
self.next.lock().clone()
4770
}
4871

4972
#[pygetset(setter)]
50-
fn set_tb_next(&self, value: Option<PyRef<Self>>) {
73+
pub fn set_tb_next(&self, value: Option<PyRef<Self>>) {
5174
*self.next.lock() = value;
5275
}
5376
}
5477

5578
impl PyTracebackRef {
5679
pub fn iter(&self) -> impl Iterator<Item = PyTracebackRef> {
57-
std::iter::successors(Some(self.clone()), |tb| tb.next.lock().clone())
80+
std::iter::successors(Some(self.clone()), |tb| tb.tb_next())
5881
}
5982
}
6083

vm/src/import.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ fn remove_importlib_frames_inner(
176176
let file_name = traceback.frame.code.source_path.as_str();
177177

178178
let (inner_tb, mut now_in_importlib) =
179-
remove_importlib_frames_inner(vm, traceback.next.lock().clone(), always_trim);
179+
remove_importlib_frames_inner(vm, traceback.tb_next(), always_trim);
180180
if file_name == "_frozen_importlib" || file_name == "_frozen_importlib_external" {
181181
if traceback.frame.code.obj_name.as_str() == "_call_with_frames_removed" {
182182
now_in_importlib = true;

0 commit comments

Comments
 (0)