Merged revisions 72776,72796 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk

........
  r72776 | jeffrey.yasskin | 2009-05-18 14:14:54 -0700 (Mon, 18 May 2009) | 6 lines

  While I was modifying test_trace, it threw an exception when I accidentally
  made it try to set the line number from the trace callback for a 'call' event.
  This patch makes the error message a little more helpful in that case, and
  makes it a little less likely that a future editor will make the same mistake
  in test_trace.
........
  r72796 | jeffrey.yasskin | 2009-05-20 10:57:57 -0700 (Wed, 20 May 2009) | 3 lines

  Fix issue #1689458 by teaching frame_setlineno how to jump to the first line of
  a code object.
........
diff --git a/Objects/frameobject.c b/Objects/frameobject.c
index e29c647..8bb0f9c 100644
--- a/Objects/frameobject.c
+++ b/Objects/frameobject.c
@@ -98,7 +98,8 @@
 	if (!f->f_trace)
 	{
 		PyErr_Format(PyExc_ValueError,
-			     "f_lineno can only be set by a trace function");
+			     "f_lineno can only be set by a"
+			     " line trace function");
 		return -1;
 	}
 
@@ -122,20 +123,26 @@
 			     new_lineno);
 		return -1;
 	}
-
-	/* Find the bytecode offset for the start of the given line, or the
-	 * first code-owning line after it. */
-	PyBytes_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. */
+		PyBytes_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;
+			}
 		}
 	}