Skip to content

Commit 941cb16

Browse files
committed
Added add_note method to PyErr
1 parent 2f4083e commit 941cb16

File tree

3 files changed

+37
-0
lines changed

3 files changed

+37
-0
lines changed

guide/src/function/error-handling.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,9 @@ fn wrapped_get_x() -> Result<i32, MyOtherError> {
231231
# }
232232
```
233233

234+
## Notes
235+
236+
In Python 3.11 and up, notes can be added to Python exceptions to provide additional debugging information when printing the exception. In PyO3, you can use the `add_note` method on `PyErr` to accomplish this functionality.
234237

235238
[`From`]: https://doc.rust-lang.org/stable/std/convert/trait.From.html
236239
[`Result<T, E>`]: https://doc.rust-lang.org/stable/std/result/enum.Result.html

newsfragments/5489.added.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Added `PyErr::add_note`

src/err/mod.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
use crate::instance::Bound;
2+
#[cfg(Py_3_11)]
3+
use crate::intern;
24
use crate::panic::PanicException;
35
use crate::type_object::PyTypeInfo;
46
use crate::types::any::PyAnyMethods;
7+
#[cfg(Py_3_11)]
8+
use crate::types::PyString;
59
use crate::types::{
610
string::PyStringMethods, traceback::PyTracebackMethods, typeobject::PyTypeMethods, PyTraceback,
711
PyTuple, PyTupleMethods, PyType,
@@ -655,6 +659,18 @@ impl PyErr {
655659
}
656660
}
657661

662+
/// Equivalent to calling `add_note` on the exception in Python.
663+
#[cfg(Py_3_11)]
664+
pub fn add_note<N: for<'py> IntoPyObject<'py, Target = PyString>>(
665+
&self,
666+
py: Python<'_>,
667+
note: N,
668+
) -> PyResult<()> {
669+
self.value(py)
670+
.call_method1(intern!(py, "add_note"), (note,))?;
671+
Ok(())
672+
}
673+
658674
#[inline]
659675
fn from_state(state: PyErrState) -> PyErr {
660676
PyErr { state }
@@ -1152,4 +1168,21 @@ mod tests {
11521168
warnings.call_method0("resetwarnings").unwrap();
11531169
});
11541170
}
1171+
1172+
#[test]
1173+
#[cfg(Py_3_11)]
1174+
fn test_add_note() {
1175+
use crate::types::any::PyAnyMethods;
1176+
Python::attach(|py| {
1177+
let err = PyErr::new::<exceptions::PyValueError, _>("original error");
1178+
err.add_note(py, "additional context").unwrap();
1179+
1180+
let notes = err.value(py).getattr("__notes__").unwrap();
1181+
assert_eq!(notes.len().unwrap(), 1);
1182+
assert_eq!(
1183+
notes.get_item(0).unwrap().extract::<String>().unwrap(),
1184+
"additional context"
1185+
);
1186+
});
1187+
}
11551188
}

0 commit comments

Comments
 (0)