-
-
Notifications
You must be signed in to change notification settings - Fork 33.1k
Open
Labels
stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytopic-IDLEtype-featureA feature request or enhancementA feature request or enhancement
Description
Feature or enhancement
Proposal:
I experimentally change the print_exception()
in idlelib.run and it can now print the ExceptionGroup:
# original
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
raise ExceptionGroup("", [NameError()])
ExceptionGroup: (1 sub-exception)
# now
+ Exception Group Traceback (most recent call last):
| File "<pyshell#1>", line 1, in <module>
| raise ExceptionGroup("", [NameError()])
| ExceptionGroup: (1 sub-exception)
+-+---------------- 1 ----------------
| NameError
+------------------------------------
The code is it:
def print_exception():
import linecache
linecache.checkcache()
flush_stdout()
efile = sys.stderr
typ, val, tb = excinfo = sys.exc_info()
sys.last_type, sys.last_value, sys.last_traceback = excinfo
sys.last_exc = val
seen = set()
def print_exc(typ, exc, tb, prefix=""):
seen.add(id(exc))
context = exc.__context__
cause = exc.__cause__
exclude = ("run.py", "rpc.py", "threading.py", "queue.py",
"debugger_r.py", "bdb.py")
if cause is not None and id(cause) not in seen:
print_exc(type(cause), cause, cause.__traceback__, prefix)
if prefix:
print(f"{prefix}|\n{prefix}| The above exception was the direct cause "
f"of the following exception:\n{prefix}|", file=efile)
else:
print("\nThe above exception was the direct cause "
"of the following exception:\n", file=efile)
elif (context is not None and
not exc.__suppress_context__ and
id(context) not in seen):
print_exc(type(context), context, context.__traceback__, prefix)
if prefix:
print(f"{prefix}|\n{prefix}| During handling of the above exception, "
f"another exception occurred:\n{prefix}|", file=efile)
else:
print("\nDuring handling of the above exception, "
"another exception occurred:\n", file=efile)
if isinstance(exc, BaseExceptionGroup):
if not prefix:
print(" + Exception Group Traceback (most recent call last):", file=efile)
else:
print(f"{prefix}| Exception Group Traceback (most recent call last):", file=efile)
if tb:
tbe = traceback.extract_tb(tb)
cleanup_traceback(tbe, exclude)
for line in traceback.format_list(tbe):
for subline in line.rstrip().splitlines():
if not prefix:
print(f" | {subline}", file=efile)
else:
print(f"{prefix}| {subline}", file=efile)
lines = get_message_lines(typ, exc, tb)
for line in lines:
if not prefix:
print(f" | {line}", end="", file=efile)
else:
print(f"{prefix}| {line}", end="", file=efile)
for i, sub in enumerate(exc.exceptions, 1):
if i == 1:
first_line_pre = "+-"
else:
first_line_pre = " "
if not prefix:
print(f" {first_line_pre}+---------------- {i} ----------------", file=efile)
else:
print(f"{prefix}{first_line_pre}+---------------- {i} ----------------", file=efile)
if id(sub) not in seen:
if not prefix:
print_exc(type(sub), sub, sub.__traceback__, " ")
else:
print_exc(type(sub), sub, sub.__traceback__, prefix + " ")
need_print_underline = not isinstance(sub, BaseExceptionGroup)
else: # avoid infinitely printing the exception
if not prefix:
print("f | <exception {type(sub).__name__} has printed>")
else:
print(f"{prefix} | <exception {type(sub).__name__} has printed>")
need_print_underline = True
if need_print_underline:
if not prefix:
print(" +------------------------------------", file=efile)
else:
print(f" {prefix}+------------------------------------", file=efile)
else:
if tb:
if prefix:
print(f"{prefix}| Traceback (most recent call last):", file=efile)
else:
print("Traceback (most recent call last):", file=efile)
tbe = traceback.extract_tb(tb)
cleanup_traceback(tbe, exclude)
if prefix:
for line in traceback.format_list(tbe):
for subline in line.rstrip().splitlines():
print(f"{prefix}| {subline}", file=efile)
else:
traceback.print_list(tbe, file=efile)
lines = get_message_lines(typ, exc, tb)
for line in lines:
if prefix:
print(f"{prefix}| {line}", end="", file=efile)
else:
print(line, end='', file=efile)
print_exc(typ, val, tb)
It is very close to the original python's ExceptionGroup output. However, it may needed more change. For example, how to deal with the print("f | <exception {type(sub).__name__} has printed>")
Has this already been discussed elsewhere?
No response given
Links to previous discussion of this feature:
No response
Linked PRs
Metadata
Metadata
Assignees
Labels
stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytopic-IDLEtype-featureA feature request or enhancementA feature request or enhancement
Projects
Status
No status