Display exception notes in tracebacks (#14039)...
Display exception notes in tracebacks (#14039)
[PEP 678](
https://peps.python.org/pep-0678/) introduced the ability to
add notes to exception objects. This has been [released in Python
3.11](
https://docs.python.org/3/library/exceptions.html#BaseException.add_note)
and is currently not implemented in IPython. These changes are fully
compatible with older Python versions that don't include PEP 678.
Here's a sample test that shows the consistency in Python's stdlib
traceback module (test 1) and the difference between Python and
IPython's runtimes (test 2):
```python
import traceback
print('--- test 1 ---')
try:
raise Exception('Testing notes')
except Exception as e:
e.add_note('Does this work?')
e.add_note('Yes!')
traceback.print_exc()
print('\n--- test 2 ---')
try:
raise Exception('Testing notes')
except Exception as e:
e.add_note('Does this work?')
e.add_note('No!')
raise
```
When executed with Python 3.11, both notes are displayed in both
tracebacks:
```
$ python test.py
--- test 1 ---
Traceback (most recent call last):
File "/app/test.py", line 5, in <module>
raise Exception('Testing notes')
Exception: Testing notes
Does this work?
Yes!
--- test 2 ---
Traceback (most recent call last):
File "/app/test.py", line 13, in <module>
raise Exception('Testing notes')
Exception: Testing notes
Does this work?
No!
```
In IPython's VerboseTB does not yet handle exception notes:
```
$ ipython test.py
--- test 1 ---
Traceback (most recent call last):
File "/app/test.py", line 5, in <module>
raise Exception('Testing notes')
Exception: Testing notes
Does this work?
Yes!
--- test 2 ---
---------------------------------------------------------------------------
Exception Traceback (most recent call last)
File /app/test.py:13
11 print('\n--- test 2 ---')
12 try:
---> 13 raise Exception('Testing notes')
14 except Exception as e:
15 e.add_note('Does this work?')
Exception: Testing notes
```
The changes I am suggesting are inspired from implementation of
[Lib/traceback.py](
https://github.com/python/cpython/blob/main/Lib/traceback.py)
(search for `__notes__`) and improvements for dealing with edge cases
more nicely in
[cpython#103897](
https://github.com/python/cpython/pull/103897).
Although notes are meant to be strings only, I kept some inspiration
from the existing exception handling to ensure that the notes are
uncolored and bytes decoded, if there are any. I am definitely open to
using a different color if deemed better. For context, `bpython` keeps
the notes uncolored, and [Python's
tutorial](
https://docs.python.org/3/tutorial/errors.html#enriching-exceptions-with-notes)
puts them in light gray, like the line numbers.
Here's how the test 2 looks like after these changes:
![image](
https://user-images.githubusercontent.com/16963011/234723689-6bbfe0ff-94d4-4a90-9da6-acfe1c8e5edf.png)
## :snake: :man_juggling: