From 0fd59f04d848a19d446959b0e3a2af5236e6427a Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Tue, 22 Mar 2022 10:07:27 +0000 Subject: [PATCH] handle frame.f_lineno is None in inspect.getframeinfo --- Lib/inspect.py | 32 ++++++++++++++++--- .../2022-03-22-10-16-11.bpo-45563.o-oP2m.rst | 1 + 2 files changed, 29 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2022-03-22-10-16-11.bpo-45563.o-oP2m.rst diff --git a/Lib/inspect.py b/Lib/inspect.py index 9c1283ab3734bfa..00dde27d9027a2e 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -1649,10 +1649,10 @@ def getframeinfo(frame, context=1): The optional second argument specifies the number of lines of context to return, which are centered around the current line.""" if istraceback(frame): - lineno = frame.tb_lineno + lineno = _tblineno(frame) frame = frame.tb_frame else: - lineno = frame.f_lineno + lineno = getlineno(frame) if not isframe(frame): raise TypeError('{!r} is not a frame or traceback object'.format(frame)) @@ -1672,10 +1672,34 @@ def getframeinfo(frame, context=1): return Traceback(filename, lineno, frame.f_code.co_name, lines, index) + +def _tblineno(tb): + tb_lineno = tb.tb_lineno + if tb_lineno is not None: + return tb_lineno + + return _lasti2lineno(tb.tb_frame.f_code, tb.tb_lasti) + + +def _lasti2lineno(code, lasti): + prev_line = code.co_firstlineno + + for start, next_line in dis.findlinestarts(code): + if lasti < start: + return prev_line + prev_line = next_line + + return prev_line + def getlineno(frame): """Get the line number from a frame object, allowing for optimization.""" - # FrameType.f_lineno is now a descriptor that grovels co_lnotab - return frame.f_lineno + # FrameType.f_lineno is now a descriptor that often grovels co_lnotab + f_lineno = frame.f_lineno + if f_lineno is not None: + return f_lineno + + return _lasti2lineno(frame.f_code, frame.f_lasti) + FrameInfo = namedtuple('FrameInfo', ('frame',) + Traceback._fields) diff --git a/Misc/NEWS.d/next/Library/2022-03-22-10-16-11.bpo-45563.o-oP2m.rst b/Misc/NEWS.d/next/Library/2022-03-22-10-16-11.bpo-45563.o-oP2m.rst new file mode 100644 index 000000000000000..d4e0076be67e11f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-03-22-10-16-11.bpo-45563.o-oP2m.rst @@ -0,0 +1 @@ +handle frame.f_lineno is None in inspect.getframeinfo