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 185 186 187 188 189 190 191 192 193 194
|
from rpython.rlib.rarithmetic import intmask
from rpython.rtyper.rrange import ll_rangelen, ll_rangeitem, ll_rangeitem_nonneg, dum_nocheck
from rpython.rtyper.lltypesystem import rrange
from rpython.rtyper.test.tool import BaseRtypingTest
class TestRrange(BaseRtypingTest):
def test_rlist_range(self):
def test1(start, stop, step, varstep):
expected = range(start, stop, step)
length = len(expected)
if varstep:
l = rrange.ll_newrangest(start, stop, step)
step = l.step
else:
RANGE = rrange.RangeRepr(step).RANGE
l = rrange.ll_newrange(RANGE, start, stop)
assert ll_rangelen(l, step) == length
lst = [ll_rangeitem(dum_nocheck, l, i, step) for i in range(length)]
assert lst == expected
lst = [ll_rangeitem_nonneg(dum_nocheck, l, i, step) for i in range(length)]
assert lst == expected
lst = [ll_rangeitem(dum_nocheck, l, i-length, step) for i in range(length)]
assert lst == expected
for start in (-10, 0, 1, 10):
for stop in (-8, 0, 4, 8, 25):
for step in (1, 2, 3, -1, -2):
for varstep in False, True:
test1(start, stop, step, varstep)
def test_range(self):
def dummyfn(N):
total = 0
for i in range(N):
total += i
return total
res = self.interpret(dummyfn, [10])
assert res == 45
def test_range_is_lazy(self):
def dummyfn(N, M):
total = 0
for i in range(M):
if i == N:
break
total += i
return total
res = self.interpret(dummyfn, [10, 2147418112])
assert res == 45
def test_range_item(self):
def dummyfn(start, stop, i):
r = range(start, stop)
return r[i]
res = self.interpret(dummyfn, [10, 17, 4])
assert res == 14
res = self.interpret(dummyfn, [10, 17, -2])
assert res == 15
def test_xrange(self):
def dummyfn(N):
total = 0
for i in xrange(N):
total += i
return total
res = self.interpret(dummyfn, [10])
assert res == 45
def test_range_len_nostep(self):
def dummyfn(start, stop):
r = range(start, stop)
return len(r)
start, stop = 10, 17
res = self.interpret(dummyfn, [start, stop])
assert res == dummyfn(start, stop)
start, stop = 17, 10
res = self.interpret(dummyfn, [start, stop])
assert res == 0
def test_range_len_step_const(self):
def dummyfn(start, stop):
r = range(start, stop, -2)
return len(r)
start, stop = 10, 17
res = self.interpret(dummyfn, [start, stop])
assert res == 0
start, stop = 17, 10
res = self.interpret(dummyfn, [start, stop])
assert res == dummyfn(start, stop)
def test_range_len_step_nonconst(self):
def dummyfn(start, stop, step):
r = range(start, stop, step)
return len(r)
start, stop, step = 10, 17, -3
res = self.interpret(dummyfn, [start, stop, step])
assert res == 0
start, stop, step = 17, 10, -3
res = self.interpret(dummyfn, [start, stop, step])
assert res == dummyfn(start, stop, step)
def test_range2list(self):
def dummyfn(start, stop):
r = range(start, stop)
r.reverse()
return r[0]
start, stop = 10, 17
res = self.interpret(dummyfn, [start, stop])
assert res == dummyfn(start, stop)
def check_failed(self, func, *args):
try:
self.interpret(func, *args, **kwargs)
except:
return True
else:
return False
def test_range_extra(self):
def failingfn_const():
r = range(10, 17, 0)
return r[-1]
assert self.check_failed(failingfn_const, [])
def failingfn_var(step):
r = range(10, 17, step)
return r[-1]
step = 3
res = self.interpret(failingfn_var, [step])
assert res == failingfn_var(step)
step = 0
assert self.check_failed(failingfn_var, [step])
def test_range_iter(self):
def fn(start, stop, step):
res = 0
if step == 0:
if stop >= start:
r = range(start, stop, 1)
else:
r = range(start, stop, -1)
else:
r = range(start, stop, step)
for i in r:
res = res * 51 + i
return res
for args in [2, 7, 0], [7, 2, 0], [10, 50, 7], [50, -10, -3]:
res = self.interpret(fn, args)
assert res == intmask(fn(*args))
def test_empty_range(self):
def g(lst):
total = 0
for i in range(len(lst)):
total += lst[i]
return total
def fn():
return g([])
res = self.interpret(fn, [])
assert res == 0
def test_enumerate(self):
def fn(n):
for i, x in enumerate([123, 456, 789, 654]):
if i == n:
return x
return 5
res = self.interpret(fn, [2])
assert res == 789
def test_enumerate_instances(self):
class A:
pass
def fn(n):
a = A()
b = A()
a.k = 10
b.k = 20
for i, x in enumerate([a, b]):
if i == n:
return x.k
return 5
res = self.interpret(fn, [1])
assert res == 20
def test_extend_range(self):
def fn(n):
lst = [n, n, n]
lst.extend(range(n))
return len(lst)
res = self.interpret(fn, [5])
assert res == 8
|