Add BaseException.add_note() and __notes__ attribute support (#6252)

This commit is contained in:
Jiseok CHOI
2025-11-14 10:31:47 +09:00
committed by GitHub
parent 4562930233
commit 9ce85862ce
2 changed files with 24 additions and 2 deletions

View File

@@ -601,7 +601,6 @@ class ExceptionTests(unittest.TestCase):
with self.assertRaisesRegex(TypeError, "state is not a dictionary"):
e.__setstate__(42)
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_notes(self):
for e in [BaseException(1), Exception(2), ValueError(3)]:
with self.subTest(e=e):

View File

@@ -4,7 +4,7 @@ use crate::object::{Traverse, TraverseFn};
use crate::{
AsObject, Context, Py, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, VirtualMachine,
builtins::{
PyNone, PyStr, PyStrRef, PyTuple, PyTupleRef, PyType, PyTypeRef,
PyList, PyNone, PyStr, PyStrRef, PyTuple, PyTupleRef, PyType, PyTypeRef,
traceback::{PyTraceback, PyTracebackRef},
},
class::{PyClassImpl, StaticType},
@@ -652,6 +652,29 @@ impl PyRef<PyBaseException> {
Ok(self)
}
#[pymethod]
fn add_note(self, note: PyStrRef, vm: &VirtualMachine) -> PyResult<()> {
let dict = self
.as_object()
.dict()
.ok_or_else(|| vm.new_attribute_error("Exception object has no __dict__"))?;
let notes = if let Ok(notes) = dict.get_item("__notes__", vm) {
notes
} else {
let new_notes = vm.ctx.new_list(vec![]);
dict.set_item("__notes__", new_notes.clone().into(), vm)?;
new_notes.into()
};
let notes = notes
.downcast::<PyList>()
.map_err(|_| vm.new_type_error("__notes__ must be a list"))?;
notes.borrow_vec_mut().push(note.into());
Ok(())
}
#[pymethod]
fn __reduce__(self, vm: &VirtualMachine) -> PyTupleRef {
if let Some(dict) = self.as_object().dict().filter(|x| !x.is_empty()) {