]> granicus.if.org Git - python/commitdiff
Bug #1512814, Fix incorrect lineno's when code within a function
authorNeal Norwitz <nnorwitz@gmail.com>
Sun, 16 Jul 2006 01:50:38 +0000 (01:50 +0000)
committerNeal Norwitz <nnorwitz@gmail.com>
Sun, 16 Jul 2006 01:50:38 +0000 (01:50 +0000)
had more than 255 blank lines.  Byte codes need to go first, line #s second.

Lib/test/test_dis.py
Misc/NEWS
Python/compile.c

index 081941dafbe9c975b808a06e534c677e23c2db3d..0aaae8feb5df7d852d519e106551c48a5fe40252 100644 (file)
@@ -81,6 +81,13 @@ dis_bug1333982 = """\
      bug1333982.func_code.co_firstlineno + 2,
      bug1333982.func_code.co_firstlineno + 3)
 
+_BIG_LINENO_FORMAT = """\
+%3d           0 LOAD_GLOBAL              0 (spam)
+              3 POP_TOP
+              4 LOAD_CONST               0 (None)
+              7 RETURN_VALUE
+"""
+
 class DisTests(unittest.TestCase):
     def do_disassembly_test(self, func, expected):
         s = StringIO.StringIO()
@@ -124,6 +131,23 @@ class DisTests(unittest.TestCase):
         if __debug__:
             self.do_disassembly_test(bug1333982, dis_bug1333982)
 
+    def test_big_linenos(self):
+        def func(count):
+           namespace = {}
+           func = "def foo():\n " + "".join(["\n "] * count + ["spam\n"])
+           exec func in namespace
+           return namespace['foo']
+
+        # Test all small ranges
+        for i in xrange(1, 300):
+            expected = _BIG_LINENO_FORMAT % (i + 2)
+            self.do_disassembly_test(func(i), expected)
+
+        # Test some larger ranges too
+        for i in xrange(300, 5000, 10):
+            expected = _BIG_LINENO_FORMAT % (i + 2)
+            self.do_disassembly_test(func(i), expected)
+
 def test_main():
     run_unittest(DisTests)
 
index 928c1b82df9ade9b11cdb7ce2a077c6f4a4e388c..f3834bbf1d5ff6250b0d21e2127e262c23fa872e 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,9 @@ What's New in Python 2.5 release candidate 1?
 Core and builtins
 -----------------
 
+- Bug #1512814, Fix incorrect lineno's when code within a function
+  had more than 255 blank lines.
+
 - Patch #1521179: Python now accepts the standard options ``--help`` and
   ``--version`` as well as ``/?`` on Windows.
 
index a96a503723fa2d35e9d9356bf2e53d8a59ebe0a6..8341cc93bbb6e8f495531307573b1f5346d4b22f 100644 (file)
@@ -4098,9 +4098,10 @@ corresponding to a bytecode address A should do something like this
 
 In order for this to work, when the addr field increments by more than 255,
 the line # increment in each pair generated must be 0 until the remaining addr
-increment is < 256.  So, in the example above, com_set_lineno should not (as
-was actually done until 2.2) expand 300, 300 to 255, 255,  45, 45, but to
-255, 0,         45, 255,  0, 45.
+increment is < 256.  So, in the example above, assemble_lnotab (it used
+to be called com_set_lineno) should not (as was actually done until 2.2)
+expand 300, 300 to 255, 255, 45, 45, 
+            but to 255,   0, 45, 255, 0, 45.
 */
 
 static int
@@ -4155,12 +4156,12 @@ assemble_lnotab(struct assembler *a, struct instr *i)
                }
                lnotab = (unsigned char *)
                           PyString_AS_STRING(a->a_lnotab) + a->a_lnotab_off;
-               *lnotab++ = 255;
                *lnotab++ = d_bytecode;
+               *lnotab++ = 255;
                d_bytecode = 0;
                for (j = 1; j < ncodes; j++) {
-                       *lnotab++ = 255;
                        *lnotab++ = 0;
+                       *lnotab++ = 255;
                }
                d_lineno -= ncodes * 255;
                a->a_lnotab_off += ncodes * 2;