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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy