Skip to content

Commit 425b178

Browse files
committed
Fix bugs in is_def_stmt and nextlineno
With wordcode will use offset+2 to advance to the next opcode
1 parent e432883 commit 425b178

5 files changed

Lines changed: 63 additions & 30 deletions

File tree

test/data/step-311.right

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ line - gcd.py:11
1616
Set stopping is off.
1717
line - gcd.py:13
1818
line - gcd.py:26
19-
(gcd.py:26): <module>
20-
-- 26 def gcd(a,b):
21-
26 -> def gcd(a,b):
19+
line - gcd.py:40
20+
(gcd.py:40): <module>
21+
-- 40 if __name__=='__main__':
22+
40 -> if __name__=='__main__':
2223
trepan3k: That's all, folks...

test/functional/example/skip.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# This code fragment what is embedded inside ../test_skippy
2+
# We have it here to make it easy to test things when things go wrong.
3+
4+
5+
# commands are:
6+
# step
7+
# skip
8+
# continue
9+
##############################
10+
x = 3
11+
x = 4
12+
y = 5
13+
y = 7 # NOQA
14+
##############################
15+
# commands are:
16+
# step
17+
# skip 2
18+
# continue
19+
x = 7
20+
x = 8
21+
x = 9
22+
y = 10 # NOQA
23+
##############################

test/functional/test_skip.py

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,33 +17,41 @@
1717

1818
def test_skip():
1919
# See that we can skip without parameter. (Same as 'skip 1'.)
20-
cmds = ["skip", "continue"]
20+
cmds = ["step", "skip", "continue"]
2121
d = strarray_setup(cmds)
2222
d.core.start()
2323
##############################
24+
x = 3
2425
x = 4
25-
x = 5
26+
y = 5
2627
y = 7 # NOQA
2728
##############################
2829
d.core.stop()
29-
out = ["-- x = 4", "-- x = 5"] # x = 4 is shown in prompt, but not *run*.
30+
# x = 4 is shown in prompt, but not *run*.
31+
out = [
32+
"-- x = 3",
33+
"-- x = 4",
34+
"-- y = 5"
35+
]
3036
compare_output(out, d)
31-
assert x == 5, "should have skipped lines"
37+
assert x == 3, "should have skipped x=4"
3238

3339
# See that we can skip with a count value
34-
cmds = ["skip 2", "continue"]
40+
cmds = ["step", "skip 2", "continue"]
3541
d = strarray_setup(cmds)
3642
d.core.start()
3743
##############################
38-
x = 10
44+
x = 7
45+
x = 8
3946
x = 9
40-
z = 7 # NOQA
47+
y = 10 # NOQA
4148
##############################
4249
d.core.stop(options={"remove": True})
4350
out = [
44-
"-- x = 10",
45-
"-- z = 7 # NOQA",
46-
] # x = 10 is shown in prompt, but not run.
51+
"-- x = 7",
52+
"-- x = 8",
53+
"-- y = 10 # NOQA",
54+
] # x = 8 is shown in prompt, but not run.
4755
compare_output(out, d)
48-
assert x == 5, "x = 10 should have been skipped"
56+
assert x == 7, "x = 8..9 should have been skipped"
4957
return

trepan/lib/bytecode.py

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
import re
2121

22-
from opcode import HAVE_ARGUMENT, opname
22+
from opcode import opname
2323
from typing import Optional
2424
from xdis import PYTHON_VERSION_TRIPLE, get_opcode_module
2525

@@ -50,10 +50,8 @@ def next_opcode(code, offset):
5050
n = len(code)
5151
while offset < n:
5252
op = code[offset]
53-
offset += 1
54-
if op >= HAVE_ARGUMENT:
55-
offset += 2
56-
pass
53+
yield op, offset
54+
offset = offset + 2
5755
yield op, offset
5856
pass
5957
yield -100, -1000
@@ -64,37 +62,40 @@ def next_linestart(co, offset: int, count=1) -> int:
6462
code = co.co_code
6563

6664
linestarts = dict(opcode_module.findlinestarts(co))
67-
# n = len(code)
65+
n = len(code)
6866
# contains_cond_jump = False
69-
for op, offset in next_opcode(code, offset):
67+
while offset < len(code):
7068
if offset in linestarts:
7169
count -= 1
7270
if 0 == count:
7371
return linestarts[offset]
7472
pass
75-
pass
73+
offset += 2
7674

7775
return -1000
7876

7977

80-
def stmt_contains_opcode(co, lineno, query_opcode) -> bool:
78+
def stmt_contains_opcode(co, lineno, query_opname) -> bool:
8179
linestarts = dict(opcode_module.findlinestarts(co))
8280
code = co.co_code
8381
found_start = False
8482
offset = 0
83+
start_line = None
8584
for offset, start_line in list(linestarts.items()):
8685
if start_line == lineno:
86+
print("=" * 30)
8787
found_start = True
8888
break
8989
pass
9090
if not found_start:
9191
return False
9292
for op, offset in next_opcode(code, offset):
93-
if -1000 == offset or linestarts.get(offset):
93+
linestart = linestarts.get(offset)
94+
if -1000 == offset or linestart and linestart != start_line:
9495
return False
95-
opcode = opname[op]
96-
# debug: print opcode
97-
if query_opcode == opcode:
96+
op_name = opname[op]
97+
# debug: print opname
98+
if query_opname == op_name:
9899
return True
99100
pass
100101
return False
@@ -104,7 +105,7 @@ def stmt_contains_opcode(co, lineno, query_opcode) -> bool:
104105
_re_def = re.compile(_re_def_str)
105106

106107

107-
def is_def_stmt(line, frame):
108+
def is_def_stmt(line: Optional[str], frame) -> bool:
108109
"""Return True if we are looking at a def statement"""
109110
# Should really also check that operand of 'LOAD_CONST' is a code object
110111
return (

trepan/processor/command/skip.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def run(self, args):
4646
return False
4747

4848
if self.proc.curframe.f_trace is None:
49-
self.errmsg("Sigh - operation can't be done here.")
49+
self.errmsg("Sigh - operation can't be done here. Frame tracing is not recorded")
5050
return False
5151

5252
if len(args) == 1:
@@ -59,7 +59,7 @@ def run(self, args):
5959
offset = self.proc.curframe.f_lasti
6060
if count is None:
6161
return False
62-
lineno = next_linestart(co, offset, count)
62+
lineno = next_linestart(co, offset+2, count)
6363

6464
if lineno < 0:
6565
self.errmsg("No next line found")

0 commit comments

Comments
 (0)