@@ -85,6 +85,7 @@ def get_info(tb_or_frame, lineno=None):
8585 filename = inspect .getsourcefile (frame ) or inspect .getfile (frame )
8686 function = frame .f_code .co_name
8787
88+
8889 try :
8990 source , startline = get_source (frame )
9091 # this can be slow (tens of ms) the first time it is called, since
@@ -95,6 +96,24 @@ def get_info(tb_or_frame, lineno=None):
9596 source = []
9697 startline = lineno
9798
99+ if lineno < startline :
100+ # Catch an edge case where the frame's current line numer is wrong,
101+ # or the discoverd line number where the frame's code block starts is.
102+ # This looks like a python bug or an `inspect.getsource` bug --
103+ # OR a getsource bug that is ultimately a python bug, because `inspect`
104+ # just uses `frame.f_code.co_firstlineno` (= the frame's own reported
105+ # beginning of its code block), and I can't imagine a situation where
106+ # that can legitimately not contain `frame.f_lineno`.
107+ # I deal with this here by showing a warning in-band that the line
108+ # number can't be 100% trusted, while also moving the active line shown
109+ # down to the first available source line.
110+ corrected_lineno = startline # move the reported active line
111+ source = ["# // Stackprinter: This frame reported a line number outside"
112+ " its reported code scope. Line %d reported, but guessing"
113+ " %d instead.\n " % (lineno , corrected_lineno )] + source
114+ startline -= 1 # account for the in-band warning prepended to our source
115+ lineno = corrected_lineno
116+
98117 source_map , line2names , name2lines , head_lns , lineno = annotate (source , startline , lineno )
99118
100119 if function in NON_FUNCTION_SCOPES :
0 commit comments