-
-
Notifications
You must be signed in to change notification settings - Fork 2k
Closed
Labels
Description
I'm pretty excited to start using PEP-654 ExceptionGroup and PEP-678 annotated exceptions in all my code (via the exceptiongroup backport, for now).
The only downside is that tools like rich.traceback (and Pytest) don't yet understand how to display these attributes - hence this feature request! I'd love to for the ecosystem to implement these new features, so that most people will have annotated-exceptiongroup-aware tooling installed by the time Python 3.11 final is released in October 😁
Repro script and output comparison between Rich and native tracebacks
from exceptiongroup import ExceptionGroup # backport; this is builtin from Python 3.11.0b1
def f():
raise ValueError("From f()")
def g():
raise RuntimeError("From g()")
def main():
excs = []
for callback in [f, g]:
try:
callback()
except Exception as err:
err.__notes__ = ["Added a note"]
excs.append(err)
if excs:
raise ExceptionGroup("Oops", excs)
def test():
try:
main()
except Exception as err:
err.__notes__ = ["Added a note"]
raise
if __name__ == "__main__":
from rich.console import Console
console = Console()
try:
test()
except Exception:
console.print_exception(show_locals=True)
print("\n\n" + "=" * 70 + "\n\n")
test() # Show the native exception display$ python repro.py
╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮
│ │
│ /mnt/c/Users/zacha/Documents/GitHub/hypothesis/repro.py:38 in <module> │
│ │
│ 35 │ console = Console() │
│ 36 │ │
│ 37 │ try: │
│ ❱ 38 │ │ test() │
│ 39 │ except Exception: │
│ 40 │ │ console.print_exception(show_locals=True) │
│ 41 │
│ │
│ ╭───────────────────────────────────────── locals ─────────────────────────────────────────╮ │
│ │ __annotations__ = {} │ │
│ │ __builtins__ = <module 'builtins' (built-in)> │ │
│ │ __cached__ = None │ │
│ │ __doc__ = None │ │
│ │ __file__ = 'repro.py' │ │
│ │ __loader__ = <_frozen_importlib_external.SourceFileLoader object at 0x7fdb0c6744c0> │ │
│ │ __name__ = '__main__' │ │
│ │ __package__ = None │ │
│ │ __spec__ = None │ │
│ │ Console = <class 'rich.console.Console'> │ │
│ │ console = <console width=138 ColorSystem.EIGHT_BIT> │ │
│ │ ExceptionGroup = <class 'exceptiongroup.ExceptionGroup'> │ │
│ │ f = <function f at 0x7fdb0bccd9d0> │ │
│ │ g = <function g at 0x7fdb0bccda60> │ │
│ │ main = <function main at 0x7fdb0bccdb80> │ │
│ │ test = <function test at 0x7fdb0bc83790> │ │
│ ╰──────────────────────────────────────────────────────────────────────────────────────────╯ │
│ /mnt/c/Users/zacha/Documents/GitHub/hypothesis/repro.py:26 in test │
│ │
│ 23 │
│ 24 def test(): │
│ 25 │ try: │
│ ❱ 26 │ │ main() │
│ 27 │ except Exception as err: │
│ 28 │ │ err.__notes__ = ["Added a note"] │
│ 29 │ │ raise │
│ │
│ /mnt/c/Users/zacha/Documents/GitHub/hypothesis/repro.py:21 in main │
│ │
│ 18 │ │ │ err.__notes__ = ["Added a note"] │
│ 19 │ │ │ excs.append(err) │
│ 20 │ if excs: │
│ ❱ 21 │ │ raise ExceptionGroup("Oops", excs) │
│ 22 │
│ 23 │
│ 24 def test(): │
│ │
│ ╭─────────────────────────── locals ────────────────────────────╮ │
│ │ callback = <function g at 0x7fdb0bccda60> │ │
│ │ excs = [ValueError('From f()'), RuntimeError('From g()')] │ │
│ ╰───────────────────────────────────────────────────────────────╯ │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
ExceptionGroup: Oops (2 sub-exceptions)
======================================================================
+ Exception Group Traceback (most recent call last):
| File "repro.py", line 43, in <module>
| test()
| File "repro.py", line 26, in test
| main()
| File "repro.py", line 21, in main
| raise ExceptionGroup("Oops", excs)
| exceptiongroup.ExceptionGroup: Oops (2 sub-exceptions)
| Added a note
+-+---------------- 1 ----------------
| Traceback (most recent call last):
| File "repro.py", line 16, in main
| callback()
| File "repro.py", line 5, in f
| raise ValueError("From f()")
| ValueError: From f()
| Added a note
+---------------- 2 ----------------
| Traceback (most recent call last):
| File "repro.py", line 16, in main
| callback()
| File "repro.py", line 9, in g
| raise RuntimeError("From g()")
| RuntimeError: From g()
| Added a note
+------------------------------------
honno, hello-fri-end and gschaffner