From 5485aeead6a4766f27f4a9f69f5310771d83ddd4 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Mon, 9 Oct 2023 14:36:17 -0700 Subject: [PATCH 1/4] Make line number of function breakpoint more precise --- Lib/pdb.py | 12 +++++++++++- Lib/test/test_pdb.py | 38 +++++++++++++++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/Lib/pdb.py b/Lib/pdb.py index 2cbd6f6746773f..c800300f37adc0 100755 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -880,7 +880,7 @@ def do_break(self, arg, temporary = 0): #use co_name to identify the bkpt (function names #could be aliased, but co_name is invariant) funcname = code.co_name - lineno = code.co_firstlineno + lineno = self._find_first_executable_line(code) filename = code.co_filename except: # last thing to try @@ -983,6 +983,16 @@ def checkline(self, filename, lineno): return 0 return lineno + def _find_first_executable_line(self, code): + """ Try to find the first executable line of the code object. + + Return code.co_firstlineno if no executable line is found. + """ + for instr in dis.get_instructions(code): + if instr.opname != 'RESUME': + return instr.positions.lineno + return code.co_firstlineno + def do_enable(self, arg): """enable bpnumber [bpnumber ...] diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index b1652e993b8a01..8ddccba396d8f1 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -1516,7 +1516,7 @@ def test_next_until_return_at_return_event(): > (3)test_function() -> test_function_2() (Pdb) break test_function_2 - Breakpoint 1 at :1 + Breakpoint 1 at :2 (Pdb) continue > (2)test_function_2() -> x = 1 @@ -2350,6 +2350,42 @@ def test_pdb_ambiguous_statements(): (Pdb) continue """ +def test_pdb_function_break(): + """Testing the line number of break on function + + >>> def foo(): pass + + >>> def bar(): + ... + ... pass + + >>> def boo(): + ... # comments + ... global x + ... x = 1 + + >>> def test_function(): + ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + ... pass + + >>> with PdbTestInput([ # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE + ... 'break foo', + ... 'break bar', + ... 'break boo', + ... 'continue' + ... ]): + ... test_function() + > (3)test_function() + -> pass + (Pdb) break foo + Breakpoint ... at :1 + (Pdb) break bar + Breakpoint ... at :3 + (Pdb) break boo + Breakpoint ... at :4 + (Pdb) continue + """ + @support.requires_subprocess() class PdbTestCase(unittest.TestCase): From fb467eb917f658a39ddde030b63efe60515d93fa Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Mon, 9 Oct 2023 14:41:17 -0700 Subject: [PATCH 2/4] Check None for lineno --- Lib/pdb.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/pdb.py b/Lib/pdb.py index c800300f37adc0..53f22f755c4919 100755 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -989,7 +989,7 @@ def _find_first_executable_line(self, code): Return code.co_firstlineno if no executable line is found. """ for instr in dis.get_instructions(code): - if instr.opname != 'RESUME': + if instr.opname != 'RESUME' and instr.positions.lineno is not None: return instr.positions.lineno return code.co_firstlineno From 80322d004b26284186064715973f93aad9c3bc08 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Mon, 9 Oct 2023 23:59:05 +0000 Subject: [PATCH 3/4] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next/Library/2023-10-09-23-59-04.gh-issue-59013.qPbS-G.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2023-10-09-23-59-04.gh-issue-59013.qPbS-G.rst diff --git a/Misc/NEWS.d/next/Library/2023-10-09-23-59-04.gh-issue-59013.qPbS-G.rst b/Misc/NEWS.d/next/Library/2023-10-09-23-59-04.gh-issue-59013.qPbS-G.rst new file mode 100644 index 00000000000000..57915f5fb4368d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-10-09-23-59-04.gh-issue-59013.qPbS-G.rst @@ -0,0 +1 @@ +Make line number of function breakpoint more precise in :mod:`pdb` From 3955333bc11d8c3b3f8aaa373a4b157b060434ad Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Wed, 11 Oct 2023 18:43:45 -0700 Subject: [PATCH 4/4] Add generator test and use instr after RESUME --- Lib/pdb.py | 11 +++++++++-- Lib/test/test_pdb.py | 10 ++++++++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/Lib/pdb.py b/Lib/pdb.py index ec4ee030af599b..a0f62175a772e7 100755 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -987,11 +987,18 @@ def checkline(self, filename, lineno): def _find_first_executable_line(self, code): """ Try to find the first executable line of the code object. + Equivalently, find the line number of the instruction that's + after RESUME + Return code.co_firstlineno if no executable line is found. """ + prev = None for instr in dis.get_instructions(code): - if instr.opname != 'RESUME' and instr.positions.lineno is not None: - return instr.positions.lineno + if prev is not None and prev.opname == 'RESUME': + if instr.positions.lineno is not None: + return instr.positions.lineno + return code.co_firstlineno + prev = instr return code.co_firstlineno def do_enable(self, arg): diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 97e5e6a945d330..c651087941f5a4 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -1938,7 +1938,7 @@ def test_pdb_next_command_in_generator_for_loop(): > (3)test_function() -> for i in test_gen(): (Pdb) break test_gen - Breakpoint 1 at :1 + Breakpoint 1 at :2 (Pdb) continue > (2)test_gen() -> yield 0 @@ -2364,6 +2364,9 @@ def test_pdb_function_break(): ... global x ... x = 1 + >>> def gen(): + ... yield 42 + >>> def test_function(): ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() ... pass @@ -2372,10 +2375,11 @@ def test_pdb_function_break(): ... 'break foo', ... 'break bar', ... 'break boo', + ... 'break gen', ... 'continue' ... ]): ... test_function() - > (3)test_function() + > (3)test_function() -> pass (Pdb) break foo Breakpoint ... at :1 @@ -2383,6 +2387,8 @@ def test_pdb_function_break(): Breakpoint ... at :3 (Pdb) break boo Breakpoint ... at :4 + (Pdb) break gen + Breakpoint ... at :2 (Pdb) continue """