diff --git a/Lib/bdb.py b/Lib/bdb.py --- a/Lib/bdb.py +++ b/Lib/bdb.py @@ -3,6 +3,7 @@ import fnmatch import sys import os +import dis __all__ = ["BdbQuit", "Bdb", "Breakpoint"] @@ -559,6 +560,9 @@ if not b.func_first_executable_line: # The function is entered for the 1st time. b.func_first_executable_line = frame.f_lineno + # see Objects/lnotab_notes.txt + b.func_first_executable_line = \ + next(dis.findlinestarts(frame.f_code))[1] if b.func_first_executable_line != frame.f_lineno: # But we are not at the first line number: don't break. diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -275,6 +275,40 @@ """ +def test_break_func_from_within_func(): + """Test that setting a breakpoint on a function from within that functions + does not cause pdb to stop at the following line. + + >>> def foo(): + ... x = 1 + ... x = 2 + + >>> def test_function(): + ... import pdb; pdb.Pdb(nosigint=True).set_trace() + ... foo() + + >>> with PdbTestInput([ + ... 'step', + ... 'step', + ... 'break foo', + ... 'continue', + ... ]): + ... test_function() + > (3)test_function() + -> foo() + (Pdb) step + --Call-- + > (1)foo() + -> def foo(): + (Pdb) step + > (2)foo() + -> x = 1 + (Pdb) break foo + Breakpoint 1 at :1 + (Pdb) continue + """ + + def do_nothing(): pass