diff --git a/Lib/bdb.py b/Lib/bdb.py index 572e5913d43..460f0d4585b 100644 --- a/Lib/bdb.py +++ b/Lib/bdb.py @@ -109,6 +109,8 @@ class Bdb: self.is_skipped_module(frame.f_globals.get('__name__')): return False if frame is self.stopframe: + if self.stoplineno == -1: + return False return frame.f_lineno >= self.stoplineno while frame is not None and frame is not self.stopframe: if frame is self.botframe: @@ -165,10 +167,12 @@ class Bdb: but only if we are to stop at or just below this level.""" pass - def _set_stopinfo(self, stopframe, returnframe, stoplineno=-1): + def _set_stopinfo(self, stopframe, returnframe, stoplineno=0): self.stopframe = stopframe self.returnframe = returnframe self.quitting = 0 + # stoplineno >= 0 means: stop at line >= the stoplineno + # stoplineno -1 means: don't stop at all self.stoplineno = stoplineno # Derived classes and clients can call the following methods @@ -184,7 +188,7 @@ class Bdb: def set_step(self): """Stop after one line of code.""" - self._set_stopinfo(None,None) + self._set_stopinfo(None, None) def set_next(self, frame): """Stop on the next line in or below the given frame.""" @@ -211,7 +215,7 @@ class Bdb: def set_continue(self): # Don't stop except at breakpoints or when finished - self._set_stopinfo(self.botframe, None) + self._set_stopinfo(self.botframe, None, -1) if not self.breaks: # no breakpoints; run without debugger overhead sys.settrace(None) diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 4af8516bd98..00ff4b7eeb0 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -122,6 +122,48 @@ def test_pdb_skip_modules_with_callback(): """ +def test_pdb_continue_in_bottomframe(): + """Test that "continue" and "next" work properly in bottom frame (issue #5294). + + >>> def test_function(): + ... import pdb, sys; inst = pdb.Pdb() + ... inst.set_trace() + ... inst.botframe = sys._getframe() # hackery to get the right botframe + ... print(1) + ... print(2) + ... print(3) + ... print(4) + + >>> with PdbTestInput([ + ... 'next', + ... 'break 7', + ... 'continue', + ... 'next', + ... 'continue', + ... 'continue', + ... ]): + ... test_function() + > (4)test_function() + -> inst.botframe = sys._getframe() # hackery to get the right botframe + (Pdb) next + > (5)test_function() + -> print(1) + (Pdb) break 7 + Breakpoint 1 at :7 + (Pdb) continue + 1 + 2 + > (7)test_function() + -> print(3) + (Pdb) next + 3 + > (8)test_function() + -> print(4) + (Pdb) continue + 4 + """ + + def pdb_invoke(method, arg): """Run pdb.method(arg).""" import pdb; getattr(pdb, method)(arg) diff --git a/Misc/NEWS b/Misc/NEWS index 50fa0cf0d79..dbe1b8a43ce 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -475,6 +475,9 @@ C-API Library ------- +- Issue #5294: Fix the behavior of pdb's "continue" command when called + in the top-level debugged frame. + - Issue #5727: Restore the ability to use readline when calling into pdb in doctests.