Exception.set_traceback_typed (#5832)

This commit is contained in:
Jeong, YunWon
2025-06-24 18:56:10 +09:00
committed by GitHub
parent a8c9703cbc
commit 3734f32e42
4 changed files with 24 additions and 7 deletions

View File

@@ -607,8 +607,6 @@ class ExceptionTests(unittest.TestCase):
self.assertIsInstance(e, MyException)
self.assertEqual(e.__traceback__, tb)
# TODO: RUSTPYTHON
@unittest.expectedFailure
def testInvalidTraceback(self):
try:
Exception().__traceback__ = 5

View File

@@ -4,7 +4,8 @@ use crate::object::{Traverse, TraverseFn};
use crate::{
AsObject, Context, Py, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, VirtualMachine,
builtins::{
PyNone, PyStr, PyStrRef, PyTuple, PyTupleRef, PyType, PyTypeRef, traceback::PyTracebackRef,
PyNone, PyStr, PyStrRef, PyTuple, PyTupleRef, PyType, PyTypeRef,
traceback::{PyTraceback, PyTracebackRef},
},
class::{PyClassImpl, StaticType},
convert::{ToPyException, ToPyObject},
@@ -324,7 +325,7 @@ impl VirtualMachine {
let ctor = ExceptionCtor::try_from_object(self, exc_type)?;
let exc = ctor.instantiate_value(exc_val, self)?;
if let Some(tb) = Option::<PyTracebackRef>::try_from_object(self, exc_tb)? {
exc.set_traceback(Some(tb));
exc.set_traceback_typed(Some(tb));
}
Ok(exc)
}
@@ -584,7 +585,25 @@ impl PyBaseException {
}
#[pygetset(magic, setter)]
pub fn set_traceback(&self, traceback: Option<PyTracebackRef>) {
pub fn set_traceback(&self, value: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
let traceback = if vm.is_none(&value) {
None
} else {
match value.downcast::<PyTraceback>() {
Ok(tb) => Some(tb),
Err(_) => {
return Err(
vm.new_type_error("__traceback__ must be a traceback or None".to_owned())
);
}
}
};
self.set_traceback_typed(traceback);
Ok(())
}
// Helper method for internal use that doesn't require PyObjectRef
pub(crate) fn set_traceback_typed(&self, traceback: Option<PyTracebackRef>) {
*self.traceback.write() = traceback;
}

View File

@@ -387,7 +387,7 @@ impl ExecutingFrame<'_> {
let new_traceback =
PyTraceback::new(next, frame.object.to_owned(), frame.lasti(), loc.row);
vm_trace!("Adding to traceback: {:?} {:?}", new_traceback, loc.row);
exception.set_traceback(Some(new_traceback.into_ref(&vm.ctx)));
exception.set_traceback_typed(Some(new_traceback.into_ref(&vm.ctx)));
vm.contextualize_exception(&exception);

View File

@@ -213,6 +213,6 @@ pub fn remove_importlib_frames(vm: &VirtualMachine, exc: &PyBaseExceptionRef) {
if let Some(tb) = exc.traceback() {
let trimmed_tb = remove_importlib_frames_inner(vm, Some(tb), always_trim).0;
exc.set_traceback(trimmed_tb);
exc.set_traceback_typed(trimmed_tb);
}
}