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. 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. CPython’s own notes give the
example of a step of 300 bytes and 200 lines, written as
255, 0, 45, 127, 0, 73.
A worked example
These bytes come from compiling the source below with CPython 3.9.6; 3.8 uses the same encoding.
x = max(
1,
2,
)
| Offset | Bytes | Instruction | Line |
|---|---|---|---|
| 0 | 65 00 | LOAD_NAME 0 (max) | 1 |
| 2 | 64 00 | LOAD_CONST 0 (1) | 2 |
| 4 | 64 01 | LOAD_CONST 1 (2) | 3 |
| 6 | 83 02 | CALL_FUNCTION 2 | 1 |
| 8 | 5A 01 | STORE_NAME 1 (x) | 1 |
| 10 | 64 02 | LOAD_CONST 2 (None) | 1 |
| 12 | 53 00 | RETURN_VALUE | 1 |
co_firstlineno is 1 and co_lnotab is
02 01 02 01 02 FE:
| Pair | Address step | Line step | Result |
|---|---|---|---|
02 01 | +2 | +1 | Offsets 0 and 1 are line 1; now address 2, line 2 |
02 01 | +2 | +1 | Offsets 2 and 3 are line 2; now address 4, line 3 |
02 FE | +2 | −2 | Offsets 4 and 5 are line 3; now address 6, line 1 |
The call at offset 6 returns to line 1, the line where the call begins, and everything after it stays there.