From 268dd5eac062f49eb25b4c1758dc5d7d85764de2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Clemens=20Kornd=C3=B6rfer?= Date: Tue, 16 Mar 2021 22:14:10 +0100 Subject: [PATCH 1/3] Change debug flag to enter pdb directly --- stackprinter/formatting.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/stackprinter/formatting.py b/stackprinter/formatting.py index cf07956..63b8699 100644 --- a/stackprinter/formatting.py +++ b/stackprinter/formatting.py @@ -195,7 +195,8 @@ def format_exc_info(etype, evalue, tb, style='plaintext', add_summary='auto', except Exception as exc: import os if 'PY_STACKPRINTER_DEBUG' in os.environ: - raise + import pdb + pdb.post_mortem(exc.__traceback__) our_tb = traceback.format_exception(exc.__class__, exc, From f6f9bb14956f2d5651100d8a10ddc772bededfc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Clemens=20Kornd=C3=B6rfer?= Date: Tue, 16 Mar 2021 22:18:11 +0100 Subject: [PATCH 2/3] Work around bug where frames report lineno outside source block --- stackprinter/extraction.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/stackprinter/extraction.py b/stackprinter/extraction.py index 936d324..ea25a2d 100644 --- a/stackprinter/extraction.py +++ b/stackprinter/extraction.py @@ -95,6 +95,24 @@ def get_info(tb_or_frame, lineno=None): source = [] startline = lineno + if lineno < startline: + # Catch rare case where the tb or frame has a wrong current line number, + # or a wrong number for the starting line of its code block. + # This looks like a python bug or an `inspect.getsource` bug -- + # OR a getsource bug that is ultimately a python bug, because `inspect` + # just uses `frame.f_code.co_firstlineno` (= the frame's own reported + # beginning of its code block), and I can't imagine a situation where + # that can legitimately not contain `frame.f_lineno`. + # I deal with this here by showing a warning in-band that the line + # number can't be 100% trusted, while also moving the active line shown + # down to the first available source line. + corrected_lineno = startline # move the reported active line + source = ["# // Stackprinter: This frame reported a line number outside" + " its reported code scope. Line %d reported, but guessing" + " %d instead.\n" % (lineno, corrected_lineno)] + source + startline -= 1 # account for the in-band warning prepended to our source + lineno = corrected_lineno + source_map, line2names, name2lines, head_lns, lineno = annotate(source, startline, lineno) if function in NON_FUNCTION_SCOPES: From a3a84f393bacfd8821a11d4d3db81c07f47e7bcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Clemens=20Kornd=C3=B6rfer?= Date: Wed, 17 Mar 2021 14:36:24 +0100 Subject: [PATCH 3/3] Extend the lineno correction hack to both too small and too large linenos --- stackprinter/extraction.py | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/stackprinter/extraction.py b/stackprinter/extraction.py index ea25a2d..8c170a9 100644 --- a/stackprinter/extraction.py +++ b/stackprinter/extraction.py @@ -95,23 +95,30 @@ def get_info(tb_or_frame, lineno=None): source = [] startline = lineno - if lineno < startline: - # Catch rare case where the tb or frame has a wrong current line number, - # or a wrong number for the starting line of its code block. - # This looks like a python bug or an `inspect.getsource` bug -- - # OR a getsource bug that is ultimately a python bug, because `inspect` - # just uses `frame.f_code.co_firstlineno` (= the frame's own reported - # beginning of its code block), and I can't imagine a situation where - # that can legitimately not contain `frame.f_lineno`. - # I deal with this here by showing a warning in-band that the line - # number can't be 100% trusted, while also moving the active line shown - # down to the first available source line. - corrected_lineno = startline # move the reported active line + # + # Catch a rare case where the tb or frame has a wrong current line number + # or maybe a wrongly reported starting line of its code block. + # This seems to be a python bug or an `inspect.getsource` bug -- + # OR a `getsource` bug that is ultimately a python bug, because `inspect` + # ultimately uses `frame.f_code.co_firstlineno` (= the frame's own reported + # beginning of its code block), and I can't imagine a situation where + # that can legitimately not contain `frame.f_lineno`. Instead of crashing, + # I deal with this here by showing a warning in-band that the line + # number can't be 100% trusted, while also moving the active line shown + # to the first available source line of the scope. + lastline = startline + len(source) - 1 + corrected_lineno = lineno + if (lineno < startline): + corrected_lineno = startline + if (lineno > lastline): + corrected_lineno = lastline + if corrected_lineno != lineno: source = ["# // Stackprinter: This frame reported a line number outside" " its reported code scope. Line %d reported, but guessing" " %d instead.\n" % (lineno, corrected_lineno)] + source startline -= 1 # account for the in-band warning prepended to our source lineno = corrected_lineno + # source_map, line2names, name2lines, head_lns, lineno = annotate(source, startline, lineno)