Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f3e4b4f

Browse files
committed
Exception.set_traceback_typed
1 parent a8c9703 commit f3e4b4f

File tree

4 files changed

+24
-7
lines changed

4 files changed

+24
-7
lines changed

Lib/test/test_exceptions.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -607,8 +607,6 @@ class MyException(Exception):
607607
self.assertIsInstance(e, MyException)
608608
self.assertEqual(e.__traceback__, tb)
609609

610-
# TODO: RUSTPYTHON
611-
@unittest.expectedFailure
612610
def testInvalidTraceback(self):
613611
try:
614612
Exception().__traceback__ = 5

vm/src/exceptions.rs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ use crate::object::{Traverse, TraverseFn};
44
use crate::{
55
AsObject, Context, Py, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, VirtualMachine,
66
builtins::{
7-
PyNone, PyStr, PyStrRef, PyTuple, PyTupleRef, PyType, PyTypeRef, traceback::PyTracebackRef,
7+
PyNone, PyStr, PyStrRef, PyTuple, PyTupleRef, PyType, PyTypeRef,
8+
traceback::{PyTraceback, PyTracebackRef},
89
},
910
class::{PyClassImpl, StaticType},
1011
convert::{ToPyException, ToPyObject},
@@ -324,7 +325,7 @@ impl VirtualMachine {
324325
let ctor = ExceptionCtor::try_from_object(self, exc_type)?;
325326
let exc = ctor.instantiate_value(exc_val, self)?;
326327
if let Some(tb) = Option::<PyTracebackRef>::try_from_object(self, exc_tb)? {
327-
exc.set_traceback(Some(tb));
328+
exc.set_traceback_typed(Some(tb));
328329
}
329330
Ok(exc)
330331
}
@@ -584,7 +585,25 @@ impl PyBaseException {
584585
}
585586

586587
#[pygetset(magic, setter)]
587-
pub fn set_traceback(&self, traceback: Option<PyTracebackRef>) {
588+
pub fn set_traceback(&self, value: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
589+
let traceback = if vm.is_none(&value) {
590+
None
591+
} else {
592+
match value.downcast::<PyTraceback>() {
593+
Ok(tb) => Some(tb),
594+
Err(_) => {
595+
return Err(
596+
vm.new_type_error("__traceback__ must be a traceback or None".to_owned())
597+
);
598+
}
599+
}
600+
};
601+
self.set_traceback_typed(traceback);
602+
Ok(())
603+
}
604+
605+
// Helper method for internal use that doesn't require PyObjectRef
606+
pub(crate) fn set_traceback_typed(&self, traceback: Option<PyTracebackRef>) {
588607
*self.traceback.write() = traceback;
589608
}
590609

vm/src/frame.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ impl ExecutingFrame<'_> {
387387
let new_traceback =
388388
PyTraceback::new(next, frame.object.to_owned(), frame.lasti(), loc.row);
389389
vm_trace!("Adding to traceback: {:?} {:?}", new_traceback, loc.row);
390-
exception.set_traceback(Some(new_traceback.into_ref(&vm.ctx)));
390+
exception.set_traceback_typed(Some(new_traceback.into_ref(&vm.ctx)));
391391

392392
vm.contextualize_exception(&exception);
393393

vm/src/import.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,6 @@ pub fn remove_importlib_frames(vm: &VirtualMachine, exc: &PyBaseExceptionRef) {
213213

214214
if let Some(tb) = exc.traceback() {
215215
let trimmed_tb = remove_importlib_frames_inner(vm, Some(tb), always_trim).0;
216-
exc.set_traceback(trimmed_tb);
216+
exc.set_traceback_typed(trimmed_tb);
217217
}
218218
}

0 commit comments

Comments
 (0)