@@ -250,31 +250,94 @@ def print_exception():
250250 sys .last_type , sys .last_value , sys .last_traceback = excinfo
251251 sys .last_exc = val
252252 seen = set ()
253+ exclude = ("run.py" , "rpc.py" , "threading.py" , "queue.py" ,
254+ "debugger_r.py" , "bdb.py" )
255+ max_group_width = 15
256+ max_group_depth = 10
257+ group_depth = 0
258+
259+ def print_exc_group (typ , exc , tb , prefix = "" ):
260+ nonlocal group_depth
261+ group_depth += 1
262+ prefix2 = prefix or " "
263+ if group_depth > max_group_depth :
264+ print (f"{ prefix2 } | ... (max_group_depth is { max_group_depth } )" ,
265+ file = efile )
266+ group_depth -= 1
267+ return
268+ if tb :
269+ if not prefix :
270+ print (" + Exception Group Traceback (most recent call last):" , file = efile )
271+ else :
272+ print (f"{ prefix } | Exception Group Traceback (most recent call last):" , file = efile )
273+ tbe = traceback .extract_tb (tb )
274+ cleanup_traceback (tbe , exclude )
275+ for line in traceback .format_list (tbe ):
276+ for subline in line .rstrip ().splitlines ():
277+ print (f"{ prefix2 } | { subline } " , file = efile )
278+ lines = get_message_lines (typ , exc , tb )
279+ for line in lines :
280+ print (f"{ prefix2 } | { line } " , end = "" , file = efile )
281+ num_excs = len (exc .exceptions )
282+ if num_excs <= max_group_width :
283+ n = num_excs
284+ else :
285+ n = max_group_width + 1
286+ for i , sub in enumerate (exc .exceptions [:n ], 1 ):
287+ truncated = (i > max_group_width )
288+ first_line_pre = "+-" if i == 1 else " "
289+ title = str (i ) if not truncated else '...'
290+ print (f"{ prefix2 } { first_line_pre } +---------------- { title } ----------------" , file = efile )
291+ if truncated :
292+ remaining = num_excs - max_group_width
293+ plural = 's' if remaining > 1 else ''
294+ print (f"{ prefix2 } | and { remaining } more exception{ plural } " ,
295+ file = efile )
296+ need_print_underline = True
297+ elif id (sub ) not in seen :
298+ if not prefix :
299+ print_exc (type (sub ), sub , sub .__traceback__ , " " )
300+ else :
301+ print_exc (type (sub ), sub , sub .__traceback__ , prefix + " " )
302+ need_print_underline = not isinstance (sub , BaseExceptionGroup )
303+ else :
304+ print (f"{ prefix2 } | <exception { type (sub ).__name__ } has printed>" , file = efile )
305+ need_print_underline = True
306+ if need_print_underline and i == n :
307+ print (f"{ prefix2 } +------------------------------------" , file = efile )
308+ group_depth -= 1
253309
254- def print_exc (typ , exc , tb ):
310+ def print_exc (typ , exc , tb , prefix = "" ):
255311 seen .add (id (exc ))
256312 context = exc .__context__
257313 cause = exc .__cause__
314+ prefix2 = f"{ prefix } | " if prefix else ""
258315 if cause is not None and id (cause ) not in seen :
259- print_exc (type (cause ), cause , cause .__traceback__ )
260- print (" \n The above exception was the direct cause "
261- "of the following exception:\n " , file = efile )
316+ print_exc (type (cause ), cause , cause .__traceback__ , prefix )
317+ print (f" { prefix2 } \n { prefix2 } The above exception was the direct cause "
318+ f "of the following exception:\n { prefix2 } " , file = efile )
262319 elif (context is not None and
263320 not exc .__suppress_context__ and
264321 id (context ) not in seen ):
265- print_exc (type (context ), context , context .__traceback__ )
266- print ("\n During handling of the above exception, "
267- "another exception occurred:\n " , file = efile )
268- if tb :
269- tbe = traceback .extract_tb (tb )
270- print ('Traceback (most recent call last):' , file = efile )
271- exclude = ("run.py" , "rpc.py" , "threading.py" , "queue.py" ,
272- "debugger_r.py" , "bdb.py" )
273- cleanup_traceback (tbe , exclude )
274- traceback .print_list (tbe , file = efile )
275- lines = get_message_lines (typ , exc , tb )
276- for line in lines :
277- print (line , end = '' , file = efile )
322+ print_exc (type (context ), context , context .__traceback__ , prefix )
323+ print (f"{ prefix2 } \n { prefix2 } During handling of the above exception, "
324+ f"another exception occurred:\n { prefix2 } " , file = efile )
325+ if isinstance (exc , BaseExceptionGroup ):
326+ print_exc_group (typ , exc , tb , prefix = prefix )
327+ else :
328+ if tb :
329+ print (f"{ prefix2 } Traceback (most recent call last):" , file = efile )
330+ tbe = traceback .extract_tb (tb )
331+ cleanup_traceback (tbe , exclude )
332+ if prefix :
333+ for line in traceback .format_list (tbe ):
334+ for subline in line .rstrip ().splitlines ():
335+ print (f"{ prefix } | { subline } " , file = efile )
336+ else :
337+ traceback .print_list (tbe , file = efile )
338+ lines = get_message_lines (typ , exc , tb )
339+ for line in lines :
340+ print (f"{ prefix2 } { line } " , end = "" , file = efile )
278341
279342 print_exc (typ , val , tb )
280343
0 commit comments