summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTian Gao <gaogaotiantian@hotmail.com>2023-10-27 21:01:31 (GMT)
committerGitHub <noreply@github.com>2023-10-27 21:01:31 (GMT)
commit1c9a0c40794f0cb3234533d5e83234e7dce4ccd4 (patch)
tree89841ac8a38baec5f00b6cfd984a283700c84859
parent77bb0d5f5047223e5d8f855ee21442ea9505834e (diff)
downloadcpython-1c9a0c40794f0cb3234533d5e83234e7dce4ccd4.zip
cpython-1c9a0c40794f0cb3234533d5e83234e7dce4ccd4.tar.gz
cpython-1c9a0c40794f0cb3234533d5e83234e7dce4ccd4.tar.bz2
gh-59013: Make line number of function breakpoint more precise (#110582)
-rwxr-xr-xLib/pdb.py19
-rw-r--r--Lib/test/test_pdb.py46
-rw-r--r--Misc/NEWS.d/next/Library/2023-10-09-23-59-04.gh-issue-59013.qPbS-G.rst1
3 files changed, 63 insertions, 3 deletions
diff --git a/Lib/pdb.py b/Lib/pdb.py
index 1e4d0a2..dbb7f55 100755
--- a/Lib/pdb.py
+++ b/Lib/pdb.py
@@ -887,7 +887,7 @@ class Pdb(bdb.Bdb, cmd.Cmd):
#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
@@ -990,6 +990,23 @@ class Pdb(bdb.Bdb, cmd.Cmd):
return 0
return 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 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):
"""enable bpnumber [bpnumber ...]
diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py
index 4701fa0..5fef836 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():
> <doctest test.test_pdb.test_next_until_return_at_return_event[1]>(3)test_function()
-> test_function_2()
(Pdb) break test_function_2
- Breakpoint 1 at <doctest test.test_pdb.test_next_until_return_at_return_event[0]>:1
+ Breakpoint 1 at <doctest test.test_pdb.test_next_until_return_at_return_event[0]>:2
(Pdb) continue
> <doctest test.test_pdb.test_next_until_return_at_return_event[0]>(2)test_function_2()
-> x = 1
@@ -1938,7 +1938,7 @@ def test_pdb_next_command_in_generator_for_loop():
> <doctest test.test_pdb.test_pdb_next_command_in_generator_for_loop[1]>(3)test_function()
-> for i in test_gen():
(Pdb) break test_gen
- Breakpoint 1 at <doctest test.test_pdb.test_pdb_next_command_in_generator_for_loop[0]>:1
+ Breakpoint 1 at <doctest test.test_pdb.test_pdb_next_command_in_generator_for_loop[0]>:2
(Pdb) continue
> <doctest test.test_pdb.test_pdb_next_command_in_generator_for_loop[0]>(2)test_gen()
-> yield 0
@@ -2350,6 +2350,48 @@ 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 gen():
+ ... yield 42
+
+ >>> 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',
+ ... 'break gen',
+ ... 'continue'
+ ... ]):
+ ... test_function()
+ > <doctest test.test_pdb.test_pdb_function_break[4]>(3)test_function()
+ -> pass
+ (Pdb) break foo
+ Breakpoint ... at <doctest test.test_pdb.test_pdb_function_break[0]>:1
+ (Pdb) break bar
+ Breakpoint ... at <doctest test.test_pdb.test_pdb_function_break[1]>:3
+ (Pdb) break boo
+ Breakpoint ... at <doctest test.test_pdb.test_pdb_function_break[2]>:4
+ (Pdb) break gen
+ Breakpoint ... at <doctest test.test_pdb.test_pdb_function_break[3]>:2
+ (Pdb) continue
+ """
+
def test_pdb_issue_gh_65052():
"""See GH-65052
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 0000000..57915f5
--- /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`