-
Notifications
You must be signed in to change notification settings - Fork 87
/
test_goto.py
184 lines (136 loc) · 4.23 KB
/
test_goto.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
import pytest
from goto import with_goto
CODE = '''\
i = 0
result = []
label .start
if i == 10:
goto .end
result.append(i)
i += 1
goto .start
label .end
'''
EXPECTED = list(range(10))
def test_range_as_code():
ns = {}
exec(with_goto(compile(CODE, '', 'exec')), ns)
assert ns['result'] == EXPECTED
def make_function(code):
lines = ['def func():']
for line in code:
lines.append(' ' + line)
lines.append(' return result')
ns = {}
exec('\n'.join(lines), ns)
return ns['func']
def test_range_as_function():
assert with_goto(make_function(CODE.splitlines()))() == EXPECTED
def test_EXTENDED_ARG():
code = []
code.append('result = True')
code.append('goto .foo')
for i in range(2**16):
code.append('label .l{0}'.format(i))
code.append('result = "dead code"')
code.append('label .foo')
assert with_goto(make_function(code))() is True
def test_jump_out_of_loop():
@with_goto
def func():
for i in range(10):
goto .end
label .end
return i
assert func() == 0
def test_jump_into_loop():
def func():
for i in range(10):
label .loop
goto .loop
pytest.raises(SyntaxError, with_goto, func)
def test_jump_out_of_nested_2_loops():
@with_goto
def func():
x = 1
for i in range(2):
for j in range(2):
# These are more than 256 bytes of bytecode
x += x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x
x += x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x
x += x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x+x
goto .end
label .end
return (i, j)
assert func() == (0, 0)
def test_jump_out_of_nested_11_loops():
@with_goto
def func():
x = 1
for i1 in range(2):
for i2 in range(2):
for i3 in range(2):
for i4 in range(2):
for i5 in range(2):
for i6 in range(2):
for i7 in range(2):
for i8 in range(2):
for i9 in range(2):
for i10 in range(2):
for i11 in range(2):
# These are more than
# 256 bytes of bytecode
x += x+x+x+x+x+x+x+x+x+x+x
x += x+x+x+x+x+x+x+x+x+x+x
x += x+x+x+x+x+x+x+x+x+x+x
x += x+x+x+x+x+x+x+x+x+x+x
x += x+x+x+x+x+x+x+x+x+x+x
goto .end
label .end
return (i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11)
assert func() == (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
def test_jump_across_loops():
def func():
for i in range(10):
goto .other_loop
for i in range(10):
label .other_loop
pytest.raises(SyntaxError, with_goto, func)
def test_jump_out_of_try_block():
@with_goto
def func():
try:
rv = None
goto .end
except Exception:
rv = 'except'
finally:
rv = 'finally'
label .end
return rv
assert func() is None
def test_jump_into_try_block():
def func():
try:
label .block
except Exception:
pass
goto .block
pytest.raises(SyntaxError, with_goto, func)
def test_jump_to_unknown_label():
def func():
goto .unknown
pytest.raises(SyntaxError, with_goto, func)
def test_jump_to_ambiguous_label():
def func():
label .ambiguous
goto .ambiguous
label .ambiguous
pytest.raises(SyntaxError, with_goto, func)
def test_function_is_copy():
def func():
pass
func.foo = 'bar'
newfunc = with_goto(func)
assert newfunc is not func
assert newfunc.foo == 'bar'