Skip to content

Commit 7d18a1c

Browse files
committed
Fix RustPython#746: invalid slice with start or stop =-1 when step<0
1 parent c5c9181 commit 7d18a1c

3 files changed

Lines changed: 2334 additions & 14 deletions

File tree

tests/snippets/builtin_slice.py

Lines changed: 66 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,24 @@
22

33
a = []
44
assert a[:] == []
5-
assert a[:2**100] == []
6-
assert a[-2**100:] == []
7-
assert a[::2**100] == []
5+
assert a[: 2 ** 100] == []
6+
assert a[-2 ** 100 :] == []
7+
assert a[:: 2 ** 100] == []
88
assert a[10:20] == []
99
assert a[-20:-10] == []
1010

1111
b = [1, 2]
1212

1313
assert b[:] == [1, 2]
14-
assert b[:2**100] == [1, 2]
15-
assert b[-2**100:] == [1, 2]
16-
assert b[2**100:] == []
17-
assert b[::2**100] == [1]
14+
assert b[: 2 ** 100] == [1, 2]
15+
assert b[-2 ** 100 :] == [1, 2]
16+
assert b[2 ** 100 :] == []
17+
assert b[:: 2 ** 100] == [1]
1818
assert b[-10:1] == [1]
1919
assert b[0:0] == []
2020
assert b[1:0] == []
2121

22-
assert_raises(ValueError, lambda: b[::0], 'zero step slice')
22+
assert_raises(ValueError, lambda: b[::0], "zero step slice")
2323

2424
assert b[::-1] == [2, 1]
2525
assert b[1::-1] == [2, 1]
@@ -33,7 +33,7 @@
3333
assert c[9:6:-3] == [9]
3434
assert c[9::-3] == [9, 6, 3, 0]
3535
assert c[9::-4] == [9, 5, 1]
36-
assert c[8::-2**100] == [8]
36+
assert c[8 :: -2 ** 100] == [8]
3737

3838
assert c[7:7:-2] == []
3939
assert c[7:8:-2] == []
@@ -43,6 +43,7 @@
4343
assert d[3::-1] == "4321"
4444
assert d[4::-3] == "52"
4545

46+
assert [1, 2, 3, 5, 6][-1:-5:-1] == [6, 5, 3, 2] # #746
4647

4748
slice_a = slice(5)
4849
assert slice_a.start is None
@@ -71,3 +72,59 @@ def __setitem__(self, key, value):
7172
ss = SubScript()
7273
_ = ss[:]
7374
ss[:1] = 1
75+
76+
77+
def test_all_slices():
78+
"""
79+
test all possible slices except big number
80+
"""
81+
MODE = None # set to "build" to rebuild slice_res.py
82+
ll = [0, 1, 2, 3]
83+
start = list(range(-7, 7))
84+
end = list(range(-7, 7))
85+
step = list(range(-5, 5))
86+
step.pop(step.index(0))
87+
88+
for i in [start, end, step]:
89+
i.append(None)
90+
91+
def build():
92+
# loop used to build slices_res.py with cpython
93+
with open("slice_res.py", "wt") as f:
94+
for s in start:
95+
for e in end:
96+
for t in step:
97+
f.write(str(ll[s:e:t]) + "\n")
98+
99+
def run():
100+
# test utility
101+
from slice_res import SLICES_RES
102+
103+
count = 0
104+
failures = []
105+
for s in start:
106+
for e in end:
107+
for t in step:
108+
lhs = ll[s:e:t]
109+
try:
110+
assert lhs == SLICES_RES[count]
111+
except AssertionError:
112+
failures.append(
113+
"start: {} ,stop: {}, step {}. Expected: {}, found: {}".format(
114+
s, e, t, lhs, SLICES_RES[count]
115+
)
116+
)
117+
count += 1
118+
119+
if failures:
120+
for f in failures:
121+
print(f)
122+
print(len(failures), "slices failed")
123+
124+
if MODE == "build":
125+
build()
126+
else:
127+
run()
128+
129+
130+
test_all_slices()

0 commit comments

Comments
 (0)