The field co_lnotab, the last in a
code object, says which source line
each instruction came from. It is a bytes object made of two-byte pairs: an address step
and a line step.
How to read it
Start with the address at 0 and the line at co_firstlineno. For each
pair, the address step is an unsigned byte and the line step is a signed byte:
a value of 0x80 or more means that value minus 256. The instructions from the current
address up to, but not including, the new address belong to the current line. Then add
both steps.
addr = 0
line = co_firstlineno
for addr_step, line_step in pairs:
if line_step >= 0x80:
line_step -= 0x100
addr += addr_step
if addr > target:
return line
line += line_step
return line
The last line reached applies to every instruction after the final pair. The line step became signed at magic 3361: a file with magic 3360 still treats it as unsigned. A negative step is possible because a later instruction can belong to an earlier line.
Large steps
A step too large for one byte is spread over several pairs. An address step over 255
uses extra pairs of 255, 0 first. A line step above 127 or below −128
uses pairs with an address step of 0 after the first.
A worked example
This example is constructed by hand from the rule above; it was not compiled by CPython 3.6. Take a module of three lines:
a = 1
b = 2
print(a + b)
Its instructions are, by the encoding on the
instructions page, two bytes each.
co_firstlineno is 1 and co_lnotab is
04 01 04 01:
| Pair | Address step | Line step | Result |
|---|---|---|---|
04 01 | +4 | +1 | Offsets 0 to 3 are line 1; now address 4, line 2 |
04 01 | +4 | +1 | Offsets 4 to 7 are line 2; now address 8, line 3 |
Offsets from 8 onwards are line 3. A signed step works the same way: in a table of
06 01 04 FF, the pair 04 FF adds 4 to the address and −1 to
the line, moving back to the previous line.