##// END OF EJS Templates
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:

File last commit:

r28248:c51f5906 merge
r28313:1d4e1847 merge
Show More
pyproject.toml
81 lines | 2.4 KiB | text/plain | TOMLLexer
[build-system]
requires = ["setuptools >= 51.0.0"]
build-backend = "setuptools.build_meta"
[tool.mypy]
python_version = 3.9
ignore_missing_imports = true
follow_imports = 'silent'
exclude = [
'test_\.+\.py',
'IPython.utils.tests.test_wildcard',
'testing',
'tests',
'PyColorize.py',
'_process_win32_controller.py',
'IPython/core/application.py',
'IPython/core/completerlib.py',
'IPython/core/displaypub.py',
'IPython/core/historyapp.py',
#'IPython/core/interactiveshell.py',
'IPython/core/magic.py',
'IPython/core/profileapp.py',
# 'IPython/core/ultratb.py',
'IPython/lib/deepreload.py',
'IPython/lib/pretty.py',
'IPython/sphinxext/ipython_directive.py',
'IPython/terminal/ipapp.py',
'IPython/utils/_process_win32.py',
'IPython/utils/path.py',
'IPython/utils/timing.py',
'IPython/utils/text.py'
]
[tool.pytest.ini_options]
addopts = [
"--durations=10",
"-pIPython.testing.plugin.pytest_ipdoctest",
"--ipdoctest-modules",
"--ignore=docs",
"--ignore=examples",
"--ignore=htmlcov",
"--ignore=ipython_kernel",
"--ignore=ipython_parallel",
"--ignore=results",
"--ignore=tmp",
"--ignore=tools",
"--ignore=traitlets",
"--ignore=IPython/core/tests/daft_extension",
"--ignore=IPython/sphinxext",
"--ignore=IPython/terminal/pt_inputhooks",
"--ignore=IPython/__main__.py",
"--ignore=IPython/external/qt_for_kernel.py",
"--ignore=IPython/html/widgets/widget_link.py",
"--ignore=IPython/html/widgets/widget_output.py",
"--ignore=IPython/terminal/console.py",
"--ignore=IPython/utils/_process_cli.py",
"--ignore=IPython/utils/_process_posix.py",
"--ignore=IPython/utils/_process_win32.py",
"--ignore=IPython/utils/_process_win32_controller.py",
"--ignore=IPython/utils/daemonize.py",
"--ignore=IPython/utils/eventful.py",
"--ignore=IPython/kernel",
"--ignore=IPython/consoleapp.py",
"--ignore=IPython/core/inputsplitter.py",
"--ignore=IPython/lib/kernel.py",
"--ignore=IPython/utils/jsonutil.py",
"--ignore=IPython/utils/localinterfaces.py",
"--ignore=IPython/utils/log.py",
"--ignore=IPython/utils/signatures.py",
"--ignore=IPython/utils/traitlets.py",
"--ignore=IPython/utils/version.py"
]
doctest_optionflags = [
"NORMALIZE_WHITESPACE",
"ELLIPSIS"
]
ipdoctest_optionflags = [
"NORMALIZE_WHITESPACE",
"ELLIPSIS"
]
asyncio_mode = "strict"