From cb7548b5d95b00cf4003ec4e36e88d6f3fa72e1a Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Fri, 18 Mar 2022 14:20:22 +0000 Subject: [PATCH] work around frame.f_lineno being None sometimes --- distributed/profile.py | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/distributed/profile.py b/distributed/profile.py index bb832735e8d..d328c6f591e 100644 --- a/distributed/profile.py +++ b/distributed/profile.py @@ -27,6 +27,8 @@ from __future__ import annotations import bisect +import dis +import itertools import linecache import sys import threading @@ -41,6 +43,31 @@ from distributed.metrics import time from distributed.utils import color_of +if sys.version_info >= (3, 10): + _pairwise = itertools.pairwise +else: + + def _pairwise(iterable): + "s -> (s0,s1), (s1,s2), (s2, s3), ..." + a, b = itertools.tee(iterable) + next(b, None) + return zip(a, b) + + +def _f_lineno(frame): + f_lineno = frame.f_lineno + if f_lineno is not None: + return f_lineno + + f_lasti = frame.f_lasti + for (_, prev_line), (start, last_line) in _pairwise( + dis.findlinestarts(frame.f_code) + ): + if f_lasti < start: + return prev_line + + return last_line + def identifier(frame): """A string identifier from a frame @@ -62,18 +89,20 @@ def identifier(frame): def repr_frame(frame): """Render a frame as a line for inclusion into a text traceback""" co = frame.f_code - text = f' File "{co.co_filename}", line {frame.f_lineno}, in {co.co_name}' - line = linecache.getline(co.co_filename, frame.f_lineno, frame.f_globals).lstrip() + f_lineno = _f_lineno(frame) + text = f' File "{co.co_filename}", line {f_lineno}, in {co.co_name}' + line = linecache.getline(co.co_filename, f_lineno, frame.f_globals).lstrip() return text + "\n\t" + line def info_frame(frame): co = frame.f_code - line = linecache.getline(co.co_filename, frame.f_lineno, frame.f_globals).lstrip() + f_lineno = _f_lineno(frame) + line = linecache.getline(co.co_filename, f_lineno, frame.f_globals).lstrip() return { "filename": co.co_filename, "name": co.co_name, - "line_number": frame.f_lineno, + "line_number": f_lineno, "line": line, }