@@ -288,11 +288,12 @@ class FrameSummary:
288288 """
289289
290290 __slots__ = ('filename' , 'lineno' , 'end_lineno' , 'colno' , 'end_colno' ,
291- 'name' , '_lines' , '_lines_dedented' , 'locals' )
291+ 'name' , '_lines' , '_lines_dedented' , 'locals' , 'cause' ,
292+ 'context' )
292293
293294 def __init__ (self , filename , lineno , name , * , lookup_line = True ,
294- locals = None , line = None ,
295- end_lineno = None , colno = None , end_colno = None ):
295+ locals = None , line = None , end_lineno = None , colno = None ,
296+ end_colno = None , cause = None , context = None ):
296297 """Construct a FrameSummary.
297298
298299 :param lookup_line: If True, `linecache` is consulted for the source
@@ -308,6 +309,8 @@ def __init__(self, filename, lineno, name, *, lookup_line=True,
308309 self .colno = colno
309310 self .end_colno = end_colno
310311 self .name = name
312+ self .cause = cause
313+ self .context = context
311314 self ._lines = line
312315 self ._lines_dedented = None
313316 if lookup_line :
@@ -462,7 +465,8 @@ def extended_frame_gen():
462465
463466 @classmethod
464467 def _extract_from_extended_frame_gen (klass , frame_gen , * , limit = None ,
465- lookup_lines = True , capture_locals = False ):
468+ lookup_lines = True , capture_locals = False , cause = None ,
469+ context = None ):
466470 # Same as extract but operates on a frame generator that yields
467471 # (frame, (lineno, end_lineno, colno, end_colno)) in the stack.
468472 # Only lineno is required, the remaining fields can be None if the
@@ -483,6 +487,8 @@ def _extract_from_extended_frame_gen(klass, frame_gen, *, limit=None,
483487
484488 result = klass ()
485489 fnames = set ()
490+ cause_frame = cause and cause .__traceback__ .tb_frame
491+ context_frame = context and context .__traceback__ .tb_frame
486492 for f , (lineno , end_lineno , colno , end_colno ) in frame_gen :
487493 co = f .f_code
488494 filename = co .co_filename
@@ -496,7 +502,9 @@ def _extract_from_extended_frame_gen(klass, frame_gen, *, limit=None,
496502 f_locals = None
497503 result .append (FrameSummary (
498504 filename , lineno , name , lookup_line = False , locals = f_locals ,
499- end_lineno = end_lineno , colno = colno , end_colno = end_colno ))
505+ end_lineno = end_lineno , colno = colno , end_colno = end_colno ,
506+ cause = cause if f is cause_frame else None ,
507+ context = context if f is context_frame else None ))
500508 for filename in fnames :
501509 linecache .checkcache (filename )
502510
@@ -536,8 +544,13 @@ def format_frame_summary(self, frame_summary, **kwargs):
536544 filename = frame_summary .filename
537545 if frame_summary .filename .startswith ("<stdin>-" ):
538546 filename = "<stdin>"
547+ notes = ''
548+ if frame_summary .cause :
549+ notes += ' (from cause)'
550+ if frame_summary .context :
551+ notes += ' (from context)'
539552 if colorize :
540- row .append (' File {}"{}"{}, line {}{}{}, in {}{}{}\n ' .format (
553+ row .append (' File {}"{}"{}, line {}{}{}, in {}{}{}{} \n ' .format (
541554 ANSIColors .MAGENTA ,
542555 filename ,
543556 ANSIColors .RESET ,
@@ -547,11 +560,12 @@ def format_frame_summary(self, frame_summary, **kwargs):
547560 ANSIColors .MAGENTA ,
548561 frame_summary .name ,
549562 ANSIColors .RESET ,
563+ notes ,
550564 )
551565 )
552566 else :
553- row .append (' File "{}", line {}, in {}\n ' .format (
554- filename , frame_summary .lineno , frame_summary .name ))
567+ row .append (' File "{}", line {}, in {}{} \n ' .format (
568+ filename , frame_summary .lineno , frame_summary .name , notes ))
555569 if frame_summary ._dedented_lines and frame_summary ._dedented_lines .strip ():
556570 if (
557571 frame_summary .colno is None or
@@ -1058,7 +1072,8 @@ def __init__(self, exc_type, exc_value, exc_traceback, *, limit=None,
10581072 self .stack = StackSummary ._extract_from_extended_frame_gen (
10591073 _walk_tb_with_full_positions (exc_traceback , _seen ),
10601074 limit = limit , lookup_lines = lookup_lines ,
1061- capture_locals = capture_locals )
1075+ capture_locals = capture_locals , cause = exc_value .__cause__ ,
1076+ context = exc_value .__context__ )
10621077
10631078 self ._exc_type = exc_type if save_exc_type else None
10641079
0 commit comments