Skip to content

Commit 9ce8586

Browse files
authored
Add BaseException.add_note() and __notes__ attribute support (RustPython#6252)
1 parent 4562930 commit 9ce8586

File tree

2 files changed

+24
-2
lines changed

2 files changed

+24
-2
lines changed

Lib/test/test_exceptions.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -601,7 +601,6 @@ def test_invalid_setstate(self):
601601
with self.assertRaisesRegex(TypeError, "state is not a dictionary"):
602602
e.__setstate__(42)
603603

604-
@unittest.expectedFailure # TODO: RUSTPYTHON
605604
def test_notes(self):
606605
for e in [BaseException(1), Exception(2), ValueError(3)]:
607606
with self.subTest(e=e):

vm/src/exceptions.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ 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,
7+
PyList, PyNone, PyStr, PyStrRef, PyTuple, PyTupleRef, PyType, PyTypeRef,
88
traceback::{PyTraceback, PyTracebackRef},
99
},
1010
class::{PyClassImpl, StaticType},
@@ -652,6 +652,29 @@ impl PyRef<PyBaseException> {
652652
Ok(self)
653653
}
654654

655+
#[pymethod]
656+
fn add_note(self, note: PyStrRef, vm: &VirtualMachine) -> PyResult<()> {
657+
let dict = self
658+
.as_object()
659+
.dict()
660+
.ok_or_else(|| vm.new_attribute_error("Exception object has no __dict__"))?;
661+
662+
let notes = if let Ok(notes) = dict.get_item("__notes__", vm) {
663+
notes
664+
} else {
665+
let new_notes = vm.ctx.new_list(vec![]);
666+
dict.set_item("__notes__", new_notes.clone().into(), vm)?;
667+
new_notes.into()
668+
};
669+
670+
let notes = notes
671+
.downcast::<PyList>()
672+
.map_err(|_| vm.new_type_error("__notes__ must be a list"))?;
673+
674+
notes.borrow_vec_mut().push(note.into());
675+
Ok(())
676+
}
677+
655678
#[pymethod]
656679
fn __reduce__(self, vm: &VirtualMachine) -> PyTupleRef {
657680
if let Some(dict) = self.as_object().dict().filter(|x| !x.is_empty()) {

0 commit comments

Comments
 (0)