diff --git a/Lib/idlelib/run.py b/Lib/idlelib/run.py index 53656806d6d..b0a47942311 100644 --- a/Lib/idlelib/run.py +++ b/Lib/idlelib/run.py @@ -158,15 +158,32 @@ def print_exception(): efile = sys.stderr typ, val, tb = excinfo = sys.exc_info() sys.last_type, sys.last_value, sys.last_traceback = excinfo - tbe = traceback.extract_tb(tb) - print('Traceback (most recent call last):', file=efile) - exclude = ("run.py", "rpc.py", "threading.py", "queue.py", - "RemoteDebugger.py", "bdb.py") - cleanup_traceback(tbe, exclude) - traceback.print_list(tbe, file=efile) - lines = traceback.format_exception_only(typ, val) - for line in lines: - print(line, end='', file=efile) + seen = set() + + def print_exc(typ, exc, tb): + seen.add(exc) + context = exc.__context__ + cause = exc.__cause__ + if cause is not None and cause not in seen: + print_exc(type(cause), cause, cause.__traceback__) + print("\nThe above exception was the direct cause " + "of the following exception:\n", file=efile) + elif context is not None and context not in seen: + print_exc(type(context), context, context.__traceback__) + print("\nDuring handling of the above exception, " + "another exception occurred:\n", file=efile) + if tb: + tbe = traceback.extract_tb(tb) + print('Traceback (most recent call last):', file=efile) + exclude = ("run.py", "rpc.py", "threading.py", "queue.py", + "RemoteDebugger.py", "bdb.py") + cleanup_traceback(tbe, exclude) + traceback.print_list(tbe, file=efile) + lines = traceback.format_exception_only(typ, exc) + for line in lines: + print(line, end='', file=efile) + + print_exc(typ, val, tb) def cleanup_traceback(tb, exclude): "Remove excluded traces from beginning/end of tb; get cached lines" diff --git a/Misc/NEWS b/Misc/NEWS index f51476aab4b..029c93007d8 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -199,6 +199,8 @@ Core and Builtins Library ------- +- Issue #16491: IDLE now prints chained exception tracebacks. + - Issue #16828: Fix error incorrectly raised by bz2.compress(''). Patch by Martin Packman.