Skip to content

Commit 94f1d7d

Browse files
committed
Update traceback.tb_next to be writable.
1 parent b1478a6 commit 94f1d7d

File tree

5 files changed

+15
-13
lines changed

5 files changed

+15
-13
lines changed

Lib/unittest/result.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -233,9 +233,8 @@ def _remove_unittest_tb_frames(self, tb):
233233
while tb and not self._is_relevant_tb_level(tb):
234234
prev = tb
235235
tb = tb.tb_next
236-
# TODO: RUSTPYTHON; traceback.tb_next is not writable yet #3857
237-
# if prev is not None:
238-
# prev.tb_next = None
236+
if prev is not None:
237+
prev.tb_next = None
239238

240239
def __repr__(self):
241240
return ("<%s run=%i errors=%i failures=%i>" %

Lib/unittest/test/test_result.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -220,8 +220,6 @@ def test_1(self):
220220
self.assertIs(test_case, test)
221221
self.assertIsInstance(formatted_exc, str)
222222

223-
# TODO: RUSTPYTHON
224-
@unittest.expectedFailure
225223
def test_addFailure_filter_traceback_frames(self):
226224
class Foo(unittest.TestCase):
227225
def test_1(self):
@@ -248,8 +246,6 @@ def get_exc_info():
248246
self.assertEqual(len(dropped), 1)
249247
self.assertIn("raise self.failureException(msg)", dropped[0])
250248

251-
# TODO: RUSTPYTHON
252-
@unittest.expectedFailure
253249
def test_addFailure_filter_traceback_frames_context(self):
254250
class Foo(unittest.TestCase):
255251
def test_1(self):

vm/src/builtins/traceback.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
use rustpython_common::lock::PyMutex;
2+
13
use super::PyType;
24
use crate::{class::PyClassImpl, frame::FrameRef, Context, Py, PyPayload, PyRef, VirtualMachine};
35

46
#[pyclass(module = false, name = "traceback")]
57
#[derive(Debug)]
68
pub struct PyTraceback {
7-
pub next: Option<PyTracebackRef>, // TODO: Make mutable
9+
pub next: PyMutex<Option<PyTracebackRef>>,
810
pub frame: FrameRef,
911
pub lasti: u32,
1012
pub lineno: usize,
@@ -22,7 +24,7 @@ impl PyPayload for PyTraceback {
2224
impl PyTraceback {
2325
pub fn new(next: Option<PyRef<Self>>, frame: FrameRef, lasti: u32, lineno: usize) -> Self {
2426
PyTraceback {
25-
next,
27+
next: PyMutex::new(next),
2628
frame,
2729
lasti,
2830
lineno,
@@ -46,13 +48,18 @@ impl PyTraceback {
4648

4749
#[pyproperty]
4850
fn tb_next(&self) -> Option<PyRef<Self>> {
49-
self.next.as_ref().cloned()
51+
self.next.lock().as_ref().cloned()
52+
}
53+
54+
#[pyproperty(setter)]
55+
fn set_tb_next(&self, value: Option<PyRef<Self>>) {
56+
*self.next.lock() = value;
5057
}
5158
}
5259

5360
impl PyTracebackRef {
5461
pub fn iter(&self) -> impl Iterator<Item = PyTracebackRef> {
55-
std::iter::successors(Some(self.clone()), |tb| tb.next.clone())
62+
std::iter::successors(Some(self.clone()), |tb| tb.next.lock().clone())
5663
}
5764
}
5865

vm/src/import.rs

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

163163
let (inner_tb, mut now_in_importlib) =
164-
remove_importlib_frames_inner(vm, traceback.next.clone(), always_trim);
164+
remove_importlib_frames_inner(vm, traceback.next.lock().clone(), always_trim);
165165
if file_name == "_frozen_importlib" || file_name == "_frozen_importlib_external" {
166166
if traceback.frame.code.obj_name.as_str() == "_call_with_frames_removed" {
167167
now_in_importlib = true;

vm/src/suggestion.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ pub fn offer_suggestions(exc: &PyBaseExceptionRef, vm: &VirtualMachine) -> Optio
5353
} else if exc.class().is(vm.ctx.exceptions.name_error) {
5454
let name = exc.as_object().to_owned().get_attr("name", vm).unwrap();
5555
let mut tb = exc.traceback().unwrap();
56-
while let Some(traceback) = tb.next.clone() {
56+
for traceback in tb.iter() {
5757
tb = traceback;
5858
}
5959

0 commit comments

Comments
 (0)