mirror of https://github.com/python/cpython
gh-59013: Make line number of function breakpoint more precise (#110582)
This commit is contained in:
parent
77bb0d5f50
commit
1c9a0c4079
19
Lib/pdb.py
19
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 ...]
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Make line number of function breakpoint more precise in :mod:`pdb`
|
Loading…
Reference in New Issue