@@ -397,18 +397,32 @@ def walk_tb(tb):
397397 tb = tb .tb_next
398398
399399
400- def _walk_tb_with_full_positions (tb ):
400+ def _get_tb_position (tb ):
401+ positions = _get_code_position (tb .tb_frame .f_code , tb .tb_lasti )
402+ # Yield tb_lineno when co_positions does not have a line number to
403+ # maintain behavior with walk_tb.
404+ if positions [0 ] is None :
405+ return tb .tb_frame , (tb .tb_lineno , ) + positions [1 :]
406+ return tb .tb_frame , positions
407+
408+
409+ def _walk_tb_with_full_positions (tb , _seen = None ):
401410 # Internal version of walk_tb that yields full code positions including
402411 # end line and column information.
412+ handler_tb = None
403413 while tb is not None :
404- positions = _get_code_position (tb .tb_frame .f_code , tb .tb_lasti )
405- # Yield tb_lineno when co_positions does not have a line number to
406- # maintain behavior with walk_tb.
407- if positions [0 ] is None :
408- yield tb .tb_frame , (tb .tb_lineno , ) + positions [1 :]
409- else :
410- yield tb .tb_frame , positions
414+ yield _get_tb_position (tb )
415+ if tb .tb_lineno != tb .tb_frame .f_lineno and _seen :
416+ for exc in reversed (_seen .values ()):
417+ if (handler_tb := exc .__traceback__ ) is not tb :
418+ while handler_tb .tb_lineno != tb .tb_frame .f_lineno :
419+ if not (handler_tb := handler_tb .tb_next ):
420+ break
421+ else :
422+ break
411423 tb = tb .tb_next
424+ if handler_tb :
425+ yield _get_tb_position (handler_tb )
412426
413427
414428def _get_code_position (code , instruction_index ):
@@ -1035,14 +1049,14 @@ def __init__(self, exc_type, exc_value, exc_traceback, *, limit=None,
10351049 # Handle loops in __cause__ or __context__.
10361050 is_recursive_call = _seen is not None
10371051 if _seen is None :
1038- _seen = set ()
1039- _seen . add ( id (exc_value ))
1052+ _seen = {}
1053+ _seen [ id (exc_value )] = exc_value
10401054
10411055 self .max_group_width = max_group_width
10421056 self .max_group_depth = max_group_depth
10431057
10441058 self .stack = StackSummary ._extract_from_extended_frame_gen (
1045- _walk_tb_with_full_positions (exc_traceback ),
1059+ _walk_tb_with_full_positions (exc_traceback , _seen ),
10461060 limit = limit , lookup_lines = lookup_lines ,
10471061 capture_locals = capture_locals )
10481062
0 commit comments