@@ -48,6 +48,9 @@ def __init__(self):
4848 # line numbers in the code block. (If it's not set, it will be
4949 # deduced).
5050 self .firstline = 0
51+ # Line number of first instruction output. Used to deduce .firstline
52+ # if it's not set explicitly.
53+ self .first_inst_lineno = 0
5154
5255 # Was replaced with ordered_blocks
5356 #self.blocks = misc.Set()
@@ -117,6 +120,8 @@ def emit(self, *inst):
117120 if len (inst ) == 2 and isinstance (inst [1 ], Block ):
118121 self .current .addOutEdge (inst [1 ])
119122 self .current .emit (inst )
123+ if inst [0 ] == "SET_LINENO" and not self .first_inst_lineno :
124+ self .first_inst_lineno = inst [1 ]
120125
121126 def getBlocksInOrder (self ):
122127 """Return the blocks in reverse postorder
@@ -545,7 +550,7 @@ def _convert_COMPARE_OP(self, arg):
545550 def makeByteCode (self ):
546551 assert self .stage == CONV
547552 self .lnotab = lnotab = LineAddrTable ()
548- lnotab .setFirstLine (self .firstline or 1 )
553+ lnotab .setFirstLine (self .firstline or self . first_inst_lineno or 1 )
549554 for t in self .insts :
550555 opname = t [0 ]
551556 if len (t ) == 1 :
@@ -577,6 +582,11 @@ def newCodeObject(self):
577582 nlocals = len (self .varnames )
578583
579584 firstline = self .firstline
585+ # For module, .firstline is initially not set, and should be first
586+ # line with actual bytecode instruction (skipping docstring, optimized
587+ # out instructions, etc.)
588+ if not firstline :
589+ firstline = self .first_inst_lineno
580590 # If no real instruction, fallback to 1
581591 if not firstline :
582592 firstline = 1
0 commit comments