[Python-checkins] cpython (2.7): issue13183 - Fix pdb skipping frames after hitting a breakpoint and running

senthil.kumaran python-checkins at python.org
Tue May 1 04:37:57 CEST 2012


http://hg.python.org/cpython/rev/5ea23739e9ba
changeset:   76677:5ea23739e9ba
branch:      2.7
parent:      76672:2468b58f7fce
user:        Senthil Kumaran <senthil at uthcode.com>
date:        Tue May 01 10:36:28 2012 +0800
summary:
  issue13183 - Fix pdb skipping frames after hitting a breakpoint and running step. Patch by Xavier de Gaye

files:
  Lib/bdb.py           |  11 ++++++
  Lib/test/test_pdb.py |  58 +++++++++++++++++++++++++++++++-
  Misc/NEWS            |   3 +
  3 files changed, 71 insertions(+), 1 deletions(-)


diff --git a/Lib/bdb.py b/Lib/bdb.py
--- a/Lib/bdb.py
+++ b/Lib/bdb.py
@@ -24,6 +24,7 @@
         self.skip = set(skip) if skip else None
         self.breaks = {}
         self.fncache = {}
+        self.frame_returning = None
 
     def canonic(self, filename):
         if filename == "<" + filename[1:-1] + ">":
@@ -82,7 +83,9 @@
 
     def dispatch_return(self, frame, arg):
         if self.stop_here(frame) or frame == self.returnframe:
+            self.frame_returning = frame
             self.user_return(frame, arg)
+            self.frame_returning = None
             if self.quitting: raise BdbQuit
         return self.trace_dispatch
 
@@ -186,6 +189,14 @@
 
     def set_step(self):
         """Stop after one line of code."""
+        # Issue #13183: pdb skips frames after hitting a breakpoint and running
+        # step commands.
+        # Restore the trace function in the caller (that may not have been set
+        # for performance reasons) when returning from the current frame.
+        if self.frame_returning:
+            caller_frame = self.frame_returning.f_back
+            if caller_frame and not caller_frame.f_trace:
+                caller_frame.f_trace = self.trace_dispatch
         self._set_stopinfo(None, None)
 
     def set_next(self, frame):
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
@@ -6,12 +6,66 @@
 import os
 import unittest
 import subprocess
+import textwrap
 
 from test import test_support
 # This little helper class is essential for testing pdb under doctest.
 from test_doctest import _FakeInput
 
 
+class PdbTestCase(unittest.TestCase):
+
+    def run_pdb(self, script, commands):
+        """Run 'script' lines with pdb and the pdb 'commands'."""
+        filename = 'main.py'
+        with open(filename, 'w') as f:
+            f.write(textwrap.dedent(script))
+        cmd = [sys.executable, '-m', 'pdb', filename]
+        stdout = stderr = None
+        proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
+                                   stdin=subprocess.PIPE,
+                                   stderr=subprocess.STDOUT,
+                                   )
+        stdout, stderr = proc.communicate(commands)
+        proc.stdout.close()
+        proc.stdin.close()
+        return stdout, stderr
+
+    def test_issue13183(self):
+        script = """
+            from bar import bar
+
+            def foo():
+                bar()
+
+            def nope():
+                pass
+
+            def foobar():
+                foo()
+                nope()
+
+            foobar()
+        """
+        commands = """
+            from bar import bar
+            break bar
+            continue
+            step
+            step
+            quit
+        """
+        bar = """
+            def bar():
+                print('1')
+        """
+        with open('bar.py', 'w') as f:
+            f.write(textwrap.dedent(bar))
+        stdout, stderr = self.run_pdb(script, commands)
+        self.assertIn('main.py(5)foo()->None', stdout.split('\n')[-3],
+                         'Fail to step into the caller after a return')
+
+
 class PdbTestInput(object):
     """Context manager that makes testing Pdb in doctests easier."""
 
@@ -309,7 +363,9 @@
 def test_main():
     from test import test_pdb
     test_support.run_doctest(test_pdb, verbosity=True)
-    test_support.run_unittest(ModuleInitTester)
+    test_support.run_unittest(
+        PdbTestCase,
+        ModuleInitTester)
 
 if __name__ == '__main__':
     test_main()
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -56,6 +56,9 @@
 Library
 -------
 
+- Issue #13183: Fix pdb skipping frames after hitting a breakpoint and running
+  step.  Patch by Xavier de Gaye.
+
 - Issue #14664: It is now possible to use @unittest.skip{If,Unless} on a
   test class that doesn't inherit from TestCase (i.e. a mixin).
 

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list