Skip to content

Commit c6618ad

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

File tree

3 files changed

+36
-0
lines changed

3 files changed

+36
-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: 32 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,17 @@ 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+
n: N,
668+
) -> PyResult<()> {
669+
self.value(py).call_method1(intern!(py, "add_note"), (n,))?;
670+
Ok(())
671+
}
672+
658673
#[inline]
659674
fn from_state(state: PyErrState) -> PyErr {
660675
PyErr { state }
@@ -1152,4 +1167,21 @@ mod tests {
11521167
warnings.call_method0("resetwarnings").unwrap();
11531168
});
11541169
}
1170+
1171+
#[test]
1172+
#[cfg(Py_3_11)]
1173+
fn test_add_note() {
1174+
use crate::types::any::PyAnyMethods;
1175+
Python::attach(|py| {
1176+
let err = PyErr::new::<exceptions::PyValueError, _>("original error");
1177+
err.add_note(py, "additional context").unwrap();
1178+
1179+
let notes = err.value(py).getattr("__notes__").unwrap();
1180+
assert_eq!(notes.len().unwrap(), 1);
1181+
assert_eq!(
1182+
notes.get_item(0).unwrap().extract::<String>().unwrap(),
1183+
"additional context"
1184+
);
1185+
});
1186+
}
11551187
}

0 commit comments

Comments
 (0)