patch by Neil Schemenauer to improve (fix?) line number generation
diff --git a/Lib/compiler/pyassem.py b/Lib/compiler/pyassem.py
index c8d9e90..74ea562 100644
--- a/Lib/compiler/pyassem.py
+++ b/Lib/compiler/pyassem.py
@@ -419,21 +419,32 @@
             # compute deltas
             addr = self.codeOffset - self.lastoff
             line = lineno - self.lastline
-            while addr > 0 or line > 0:
-                # write the values in 1-byte chunks that sum
-                # to desired value
-                trunc_addr = addr
-                trunc_line = line
-                if trunc_addr > 255:
-                    trunc_addr = 255
-                if trunc_line > 255:
-                    trunc_line = 255
-                self.lnotab.append(trunc_addr)
-                self.lnotab.append(trunc_line)
-                addr = addr - trunc_addr
-                line = line - trunc_line
-            self.lastline = lineno
-            self.lastoff = self.codeOffset
+            # Python assumes that lineno always increases with
+            # increasing bytecode address (lnotab is unsigned char).
+            # Depending on when SET_LINENO instructions are emitted
+            # this is not always true.  Consider the code:
+            #     a = (1,
+            #          b)
+            # In the bytecode stream, the assignment to "a" occurs
+            # after the loading of "b".  This works with the C Python
+            # compiler because it only generates a SET_LINENO instruction
+            # for the assignment.
+            if line > 0:
+                while addr > 0 or line > 0:
+                    # write the values in 1-byte chunks that sum
+                    # to desired value
+                    trunc_addr = addr
+                    trunc_line = line
+                    if trunc_addr > 255:
+                        trunc_addr = 255
+                    if trunc_line > 255:
+                        trunc_line = 255
+                    self.lnotab.append(trunc_addr)
+                    self.lnotab.append(trunc_line)
+                    addr = addr - trunc_addr
+                    line = line - trunc_line
+                self.lastline = lineno
+                self.lastoff = self.codeOffset
 
     def getCode(self):
         return string.join(self.code, '')
diff --git a/Lib/compiler/pycodegen.py b/Lib/compiler/pycodegen.py
index a4c9e5b..2a1b308 100644
--- a/Lib/compiler/pycodegen.py
+++ b/Lib/compiler/pycodegen.py
@@ -70,6 +70,7 @@
         self.loops = misc.Stack()
         self.curStack = 0
         self.maxStack = 0
+        self.last_lineno = None
         self._setupGraphDelegation()
 
     def _setupGraphDelegation(self):
@@ -107,7 +108,8 @@
             self.emit(prefix + '_GLOBAL', name)
 
     def set_lineno(self, node):
-        """Emit SET_LINENO if node has lineno attribute
+        """Emit SET_LINENO if node has lineno attribute and it is 
+        different than the last lineno emitted.
 
         Returns true if SET_LINENO was emitted.
 
@@ -117,8 +119,9 @@
         then, this method works around missing line numbers.
         """
         lineno = getattr(node, 'lineno', None)
-        if lineno is not None:
+        if lineno is not None and lineno != self.last_lineno:
             self.emit('SET_LINENO', lineno)
+            self.last_lineno = lineno
             return 1
         return 0
 
@@ -414,6 +417,7 @@
         pass
 
     def visitName(self, node):
+        self.set_lineno(node)
         self.loadName(node.name)
         
     def visitPass(self, node):
diff --git a/Tools/compiler/compiler/pyassem.py b/Tools/compiler/compiler/pyassem.py
index c8d9e90..74ea562 100644
--- a/Tools/compiler/compiler/pyassem.py
+++ b/Tools/compiler/compiler/pyassem.py
@@ -419,21 +419,32 @@
             # compute deltas
             addr = self.codeOffset - self.lastoff
             line = lineno - self.lastline
-            while addr > 0 or line > 0:
-                # write the values in 1-byte chunks that sum
-                # to desired value
-                trunc_addr = addr
-                trunc_line = line
-                if trunc_addr > 255:
-                    trunc_addr = 255
-                if trunc_line > 255:
-                    trunc_line = 255
-                self.lnotab.append(trunc_addr)
-                self.lnotab.append(trunc_line)
-                addr = addr - trunc_addr
-                line = line - trunc_line
-            self.lastline = lineno
-            self.lastoff = self.codeOffset
+            # Python assumes that lineno always increases with
+            # increasing bytecode address (lnotab is unsigned char).
+            # Depending on when SET_LINENO instructions are emitted
+            # this is not always true.  Consider the code:
+            #     a = (1,
+            #          b)
+            # In the bytecode stream, the assignment to "a" occurs
+            # after the loading of "b".  This works with the C Python
+            # compiler because it only generates a SET_LINENO instruction
+            # for the assignment.
+            if line > 0:
+                while addr > 0 or line > 0:
+                    # write the values in 1-byte chunks that sum
+                    # to desired value
+                    trunc_addr = addr
+                    trunc_line = line
+                    if trunc_addr > 255:
+                        trunc_addr = 255
+                    if trunc_line > 255:
+                        trunc_line = 255
+                    self.lnotab.append(trunc_addr)
+                    self.lnotab.append(trunc_line)
+                    addr = addr - trunc_addr
+                    line = line - trunc_line
+                self.lastline = lineno
+                self.lastoff = self.codeOffset
 
     def getCode(self):
         return string.join(self.code, '')
diff --git a/Tools/compiler/compiler/pycodegen.py b/Tools/compiler/compiler/pycodegen.py
index a4c9e5b..2a1b308 100644
--- a/Tools/compiler/compiler/pycodegen.py
+++ b/Tools/compiler/compiler/pycodegen.py
@@ -70,6 +70,7 @@
         self.loops = misc.Stack()
         self.curStack = 0
         self.maxStack = 0
+        self.last_lineno = None
         self._setupGraphDelegation()
 
     def _setupGraphDelegation(self):
@@ -107,7 +108,8 @@
             self.emit(prefix + '_GLOBAL', name)
 
     def set_lineno(self, node):
-        """Emit SET_LINENO if node has lineno attribute
+        """Emit SET_LINENO if node has lineno attribute and it is 
+        different than the last lineno emitted.
 
         Returns true if SET_LINENO was emitted.
 
@@ -117,8 +119,9 @@
         then, this method works around missing line numbers.
         """
         lineno = getattr(node, 'lineno', None)
-        if lineno is not None:
+        if lineno is not None and lineno != self.last_lineno:
             self.emit('SET_LINENO', lineno)
+            self.last_lineno = lineno
             return 1
         return 0
 
@@ -414,6 +417,7 @@
         pass
 
     def visitName(self, node):
+        self.set_lineno(node)
         self.loadName(node.name)
         
     def visitPass(self, node):