From 2809b92448612eec556dbf30ff0ec52a5e514a45 Mon Sep 17 00:00:00 2001 From: Rich Chiodo Date: Mon, 2 Dec 2024 10:04:40 -0800 Subject: [PATCH 1/2] Fix problem with lineno being none when generating traceback Fixes https://github.com/microsoft/debugpy/issues/1745 --- .../_vendored/pydevd/_pydevd_bundle/pydevd_comm.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_comm.py b/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_comm.py index b70d7dcac..b8aea2cf5 100644 --- a/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_comm.py +++ b/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_comm.py @@ -1523,12 +1523,13 @@ def build_exception_info_response(dbg, thread_id, thread, request_seq, set_addit if IS_PY311_OR_GREATER: stack_summary = traceback.StackSummary() for filename_in_utf8, lineno, method_name, line_text, line_col_info in frames[-max_frames:]: - frame_summary = traceback.FrameSummary(filename_in_utf8, lineno, method_name, line=line_text) - if line_col_info is not None: - frame_summary.end_lineno = line_col_info.end_lineno - frame_summary.colno = line_col_info.colno - frame_summary.end_colno = line_col_info.end_colno - stack_summary.append(frame_summary) + if lineno is not None: + frame_summary = traceback.FrameSummary(filename_in_utf8, lineno, method_name, line=line_text) + if line_col_info is not None and line_col_info.end_lineno is not None: + frame_summary.end_lineno = line_col_info.end_lineno + frame_summary.colno = line_col_info.colno + frame_summary.end_colno = line_col_info.end_colno + stack_summary.append(frame_summary) stack_str = "".join(stack_summary.format()) From 5ef7e207967b94b46ed736a40f09c953de586418 Mon Sep 17 00:00:00 2001 From: Rich Chiodo Date: Mon, 2 Dec 2024 10:46:38 -0800 Subject: [PATCH 2/2] Improve multiline statement handling in stack summary --- .../pydevd/_pydevd_bundle/pydevd_comm.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_comm.py b/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_comm.py index b8aea2cf5..d855b3966 100644 --- a/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_comm.py +++ b/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_comm.py @@ -1523,12 +1523,21 @@ def build_exception_info_response(dbg, thread_id, thread, request_seq, set_addit if IS_PY311_OR_GREATER: stack_summary = traceback.StackSummary() for filename_in_utf8, lineno, method_name, line_text, line_col_info in frames[-max_frames:]: - if lineno is not None: + if line_col_info is not None: + # End line might mean that we have a multiline statement. + if line_col_info.end_lineno is not None and lineno < line_col_info.end_lineno: + line_text = "\n".join(linecache.getlines(filename_in_utf8)[lineno : line_col_info.end_lineno + 1]) + frame_summary = traceback.FrameSummary( + filename_in_utf8, + lineno, + method_name, + line=line_text, + end_lineno=line_col_info.end_lineno, + colno=line_col_info.colno, + end_colno=line_col_info.end_colno) + stack_summary.append(frame_summary) + else: frame_summary = traceback.FrameSummary(filename_in_utf8, lineno, method_name, line=line_text) - if line_col_info is not None and line_col_info.end_lineno is not None: - frame_summary.end_lineno = line_col_info.end_lineno - frame_summary.colno = line_col_info.colno - frame_summary.end_colno = line_col_info.end_colno stack_summary.append(frame_summary) stack_str = "".join(stack_summary.format())