Skip to content

Commit ba695e4

Browse files
authored
Merge pull request #160 from 2elli/3.10-fix-co_lines
Python 3.10 fix co_lines parsing of co_linetable
2 parents 793102c + 557ee34 commit ba695e4

1 file changed

Lines changed: 18 additions & 10 deletions

File tree

xdis/codetype/code310.py

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -163,24 +163,32 @@ def co_lines(self):
163163
either be a positive integer, or None
164164
165165
Parsing implementation adapted from: https://github.com/python/cpython/blob/3.10/Objects/lnotab_notes.txt
166+
The algorithm presented in the lnotab_notes.txt file is slightly inaccurate. The first linetable entry will have a line delta of 0, and should be yielded instead of skipped.
167+
This implementation follows the lineiter definition in https://github.com/python/cpython/blob/3.10/Objects/codeobject.c#L1030.
166168
"""
167-
line = self.co_firstlineno
168169
end_offset = 0
170+
line = self.co_firstlineno
171+
169172
# co_linetable is pairs of (offset_delta: unsigned byte, line_delta: signed byte)
170173
for offset_delta, line_delta in struct.iter_unpack('=Bb', self.co_linetable):
171174
assert isinstance(line_delta, int)
172175
assert isinstance(offset_delta, int)
173-
if line_delta == 0: # No change to line number, just accumulate changes to end
174-
end_offset += offset_delta
175-
continue
176+
176177
start_offset = end_offset
177-
end_offset = start_offset + offset_delta
178-
if line_delta == -128: # No valid line number -- skip entry
179-
continue
180-
line += line_delta
181-
if end_offset == start_offset: # Empty range, omit.
178+
end_offset += offset_delta
179+
180+
# line_delta of -128 signifies an instruction range that is not associated with any line
181+
if line_delta != -128:
182+
line += line_delta
183+
display_line = line
184+
else:
185+
display_line = None
186+
187+
# omit empty ranges
188+
if start_offset == end_offset:
182189
continue
183-
yield start_offset, end_offset, line
190+
191+
yield start_offset, end_offset, display_line
184192

185193
def encode_lineno_tab(self):
186194
"""

0 commit comments

Comments
 (0)