[Python-checkins] r72796 - in python/trunk: Lib/test/test_trace.py Objects/frameobject.c

jeffrey.yasskin python-checkins at python.org
Wed May 20 19:57:57 CEST 2009


Author: jeffrey.yasskin
Date: Wed May 20 19:57:57 2009
New Revision: 72796

Log:
Fix issue #1689458 by teaching frame_setlineno how to jump to the first line of
a code object.


Modified:
   python/trunk/Lib/test/test_trace.py
   python/trunk/Objects/frameobject.c

Modified: python/trunk/Lib/test/test_trace.py
==============================================================================
--- python/trunk/Lib/test/test_trace.py	(original)
+++ python/trunk/Lib/test/test_trace.py	Wed May 20 19:57:57 2009
@@ -740,6 +740,27 @@
     def test_19_no_jump_without_trace_function(self):
         no_jump_without_trace_function()
 
+    def test_jump_to_firstlineno(self):
+        # This tests that PDB can jump back to the first line in a
+        # file.  See issue #1689458.  It can only be triggered in a
+        # function call if the function is defined on a single line.
+        code = compile("""
+# Comments don't count.
+output.append(2)  # firstlineno is here.
+output.append(3)
+output.append(4)
+""", "<fake module>", "exec")
+        class fake_function:
+            func_code = code
+            jump = (2, 0)
+        tracer = JumpTracer(fake_function)
+        sys.settrace(tracer.trace)
+        namespace = {"output": []}
+        exec code in namespace
+        sys.settrace(None)
+        self.compare_jump_output([2, 3, 2, 3, 4], namespace["output"])
+
+
 def test_main():
     test_support.run_unittest(
         TraceTestCase,

Modified: python/trunk/Objects/frameobject.c
==============================================================================
--- python/trunk/Objects/frameobject.c	(original)
+++ python/trunk/Objects/frameobject.c	Wed May 20 19:57:57 2009
@@ -140,20 +140,26 @@
 			     new_lineno);
 		return -1;
 	}
-
-	/* Find the bytecode offset for the start of the given line, or the
-	 * first code-owning line after it. */
-	PyString_AsStringAndSize(f->f_code->co_lnotab, &lnotab, &lnotab_len);
-	addr = 0;
-	line = f->f_code->co_firstlineno;
-	new_lasti = -1;
-	for (offset = 0; offset < lnotab_len; offset += 2) {
-		addr += lnotab[offset];
-		line += lnotab[offset+1];
-		if (line >= new_lineno) {
-			new_lasti = addr;
-			new_lineno = line;
-			break;
+	else if (new_lineno == f->f_code->co_firstlineno) {
+		new_lasti = 0;
+		new_lineno = f->f_code->co_firstlineno;
+	}
+	else {
+		/* Find the bytecode offset for the start of the given
+		 * line, or the first code-owning line after it. */
+		PyString_AsStringAndSize(f->f_code->co_lnotab,
+					 &lnotab, &lnotab_len);
+		addr = 0;
+		line = f->f_code->co_firstlineno;
+		new_lasti = -1;
+		for (offset = 0; offset < lnotab_len; offset += 2) {
+			addr += lnotab[offset];
+			line += lnotab[offset+1];
+			if (line >= new_lineno) {
+				new_lasti = addr;
+				new_lineno = line;
+				break;
+			}
 		}
 	}
 


More information about the Python-checkins mailing list