Skip to content

Commit 683d06e

Browse files
committed
Merge branch 'bradmwalker-more-range-work' into v0.14.x
2 parents 9ea63f7 + 54bea45 commit 683d06e

2 files changed

Lines changed: 155 additions & 69 deletions

File tree

src/future/types/newrange.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,11 @@ def __getitem_slice(self, slce):
126126
"""Return a range which represents the requested slce
127127
of the sequence represented by this range.
128128
"""
129-
start, stop, step = slce.indices(self._len)
130-
return newrange(self._start + self._step*start,
131-
self._start + stop,
132-
self._step * step)
129+
scaled_indices = (self._step * n for n in slce.indices(self._len))
130+
start_offset, stop_offset, new_step = scaled_indices
131+
return newrange(self._start + start_offset,
132+
self._start + stop_offset,
133+
new_step)
133134

134135
def __iter__(self):
135136
"""Return an iterator which enumerates the elements of the

tests/test_future/test_range.py

Lines changed: 150 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from future.tests.base import unittest
88

99
from collections import Iterator, Sequence
10+
from operator import attrgetter
1011

1112

1213
class RangeTests(unittest.TestCase):
@@ -25,79 +26,163 @@ def test_equality_range(self):
2526
self.assertEqual(range(0), range(1, 1))
2627
self.assertEqual(range(0, 10, 3), range(0, 11, 3))
2728

28-
def test_slice_empty_range(self):
29-
self.assertEqual(range(0)[:], range(0))
30-
self.assertEqual(range(0)[::-1], range(-1, -1, -1))
29+
# Use strict equality of attributes when slicing to catch subtle differences
30+
def assertRangesEqual(self, r1, r2):
31+
by_attrs = attrgetter('start', 'stop', 'step')
32+
self.assertEqual(by_attrs(r1), by_attrs(r2))
3133

32-
def test_slice_range(self):
33-
r = range(8)
34-
self.assertEqual(r[:], range(8))
35-
self.assertEqual(r[:2], range(2))
36-
self.assertEqual(r[:-2], range(6))
37-
self.assertEqual(r[2:], range(2, 8))
38-
self.assertEqual(r[-2:], range(6, 8))
39-
self.assertEqual(r[2:-2], range(2, 6))
40-
self.assertEqual(r[-2:2:-1], range(6, 2, -1))
41-
r = r[::-1]
42-
self.assertEqual(r, range(7, -1, -1))
43-
self.assertEqual(r[:], range(7, -1, -1))
44-
self.assertEqual(r[:2], range(7, 5, -1))
45-
self.assertEqual(r[:-2], range(7, 1, -1))
46-
self.assertEqual(r[2:], range(5, -1, -1))
47-
self.assertEqual(r[-2:], range(1, -1, -1))
48-
self.assertEqual(r[2:-2], range(5, 1, -1))
49-
self.assertEqual(r[-2:2:-1], range(1, 5))
50-
51-
def test_slice_offsetted_range(self):
52-
r = range(4, 16)
53-
self.assertEqual(r[:], range(4, 16))
54-
self.assertEqual(r[::-1], range(15, 3, -1))
55-
self.assertEqual(r[:4], range(4, 8))
56-
self.assertEqual(r[:-4], range(4, 12))
57-
self.assertEqual(r[4:], range(8, 16))
58-
self.assertEqual(r[-4:], range(12, 16))
59-
self.assertEqual(r[4:-4], range(8, 12))
60-
self.assertEqual(r[-4:4:-1], range(12, 8, -1))
34+
def test_slice_empty_range(self):
35+
self.assertRangesEqual(range(0)[:], range(0))
36+
self.assertRangesEqual(range(0)[::-1], range(-1, -1, -1))
6137

6238
def test_slice_overflow_range(self):
6339
r = range(8)
64-
self.assertEqual(r[2:200], range(2, 8))
65-
self.assertEqual(r[-200:-2], range(0, 6))
40+
self.assertRangesEqual(r[2:200], range(2, 8))
41+
self.assertRangesEqual(r[-200:-2], range(0, 6))
42+
43+
def test_slice_range(self):
44+
r = range(-8, 8)
45+
self.assertRangesEqual(r[:], range(-8, 8))
46+
self.assertRangesEqual(r[:2], range(-8, -6))
47+
self.assertRangesEqual(r[:-2], range(-8, 6))
48+
self.assertRangesEqual(r[2:], range(-6, 8))
49+
self.assertRangesEqual(r[-2:], range(6, 8))
50+
self.assertRangesEqual(r[2:-2], range(-6, 6))
51+
52+
def test_rev_slice_range(self):
53+
r = range(-8, 8)
54+
self.assertRangesEqual(r[::-1], range(7, -9, -1))
55+
self.assertRangesEqual(r[:2:-1], range(7, -6, -1))
56+
self.assertRangesEqual(r[:-2:-1], range(7, 6, -1))
57+
self.assertRangesEqual(r[2::-1], range(-6, -9, -1))
58+
self.assertRangesEqual(r[-2::-1], range(6, -9, -1))
59+
self.assertRangesEqual(r[-2:2:-1], range(6, -6, -1))
60+
61+
def test_slice_rev_range(self):
62+
r = range(8, -8, -1)
63+
self.assertRangesEqual(r[:], range(8, -8, -1))
64+
self.assertRangesEqual(r[:2], range(8, 6, -1))
65+
self.assertRangesEqual(r[:-2], range(8, -6, -1))
66+
self.assertRangesEqual(r[2:], range(6, -8, -1))
67+
self.assertRangesEqual(r[-2:], range(-6, -8, -1))
68+
self.assertRangesEqual(r[2:-2], range(6, -6, -1))
69+
70+
def test_rev_slice_rev_range(self):
71+
r = range(8, -8, -1)
72+
self.assertRangesEqual(r[::-1], range(-7, 9))
73+
self.assertRangesEqual(r[:2:-1], range(-7, 6))
74+
self.assertRangesEqual(r[:-2:-1], range(-7, -6))
75+
self.assertRangesEqual(r[2::-1], range(6, 9))
76+
self.assertRangesEqual(r[-2::-1], range(-6, 9))
77+
self.assertRangesEqual(r[-2:2:-1], range(-6, 6))
6678

6779
def test_stepped_slice_range(self):
68-
r = range(8)
69-
self.assertEqual(r[::2], range(0, 8, 2))
70-
self.assertEqual(r[::-2], range(7, -1, -2))
71-
self.assertEqual(r[:2:2], range(0, 2, 2))
72-
self.assertEqual(r[:-2:2], range(0, 6, 2))
73-
self.assertEqual(r[2::2], range(2, 8, 2))
74-
self.assertEqual(r[-2::2], range(6, 8, 2))
75-
self.assertEqual(r[2:-2:2], range(2, 6, 2))
80+
r = range(-8, 8)
81+
self.assertRangesEqual(r[::2], range(-8, 8, 2))
82+
self.assertRangesEqual(r[:2:2], range(-8, -6, 2))
83+
self.assertRangesEqual(r[:-2:2], range(-8, 6, 2))
84+
self.assertRangesEqual(r[2::2], range(-6, 8, 2))
85+
self.assertRangesEqual(r[-2::2], range(6, 8, 2))
86+
self.assertRangesEqual(r[2:-2:2], range(-6, 6, 2))
87+
88+
def test_rev_stepped_slice_range(self):
89+
r = range(-8, 8)
90+
self.assertRangesEqual(r[::-2], range(7, -9, -2))
91+
self.assertRangesEqual(r[:2:-2], range(7, -6, -2))
92+
self.assertRangesEqual(r[:-2:-2], range(7, 6, -2))
93+
self.assertRangesEqual(r[2::-2], range(-6, -9, -2))
94+
self.assertRangesEqual(r[-2::-2], range(6, -9, -2))
95+
self.assertRangesEqual(r[-2:2:-2], range(6, -6, -2))
96+
97+
def test_stepped_slice_rev_range(self):
98+
r = range(8, -8, -1)
99+
self.assertRangesEqual(r[::2], range(8, -8, -2))
100+
self.assertRangesEqual(r[:2:2], range(8, 6, -2))
101+
self.assertRangesEqual(r[:-2:2], range(8, -6, -2))
102+
self.assertRangesEqual(r[2::2], range(6, -8, -2))
103+
self.assertRangesEqual(r[-2::2], range(-6, -8, -2))
104+
self.assertRangesEqual(r[2:-2:2], range(6, -6, -2))
105+
106+
def test_rev_stepped_slice_rev_range(self):
107+
r = range(8, -8, -1)
108+
self.assertRangesEqual(r[::-2], range(-7, 9, 2))
109+
self.assertRangesEqual(r[:2:-2], range(-7, 6, 2))
110+
self.assertRangesEqual(r[:-2:-2], range(-7, -6, 2))
111+
self.assertRangesEqual(r[2::-2], range(6, 9, 2))
112+
self.assertRangesEqual(r[-2::-2], range(-6, 9, 2))
113+
self.assertRangesEqual(r[-2:2:-2], range(-6, 6, 2))
114+
115+
def test_slice_stepped_range(self):
116+
r = range(-8, 8, 2)
117+
self.assertRangesEqual(r[:], range(-8, 8, 2))
118+
self.assertRangesEqual(r[:2], range(-8, -4, 2))
119+
self.assertRangesEqual(r[:-2], range(-8, 4, 2))
120+
self.assertRangesEqual(r[2:], range(-4, 8, 2))
121+
self.assertRangesEqual(r[-2:], range(4, 8, 2))
122+
self.assertRangesEqual(r[2:-2], range(-4, 4, 2))
123+
124+
def test_rev_slice_stepped_range(self):
125+
r = range(-8, 8, 2)
126+
self.assertRangesEqual(r[::-1], range(6, -10, -2))
127+
self.assertRangesEqual(r[:2:-1], range(6, -4, -2))
128+
self.assertRangesEqual(r[:-2:-1], range(6, 4, -2))
129+
self.assertRangesEqual(r[2::-1], range(-4, -10, -2))
130+
self.assertRangesEqual(r[-2::-1], range(4, -10, -2))
131+
self.assertRangesEqual(r[-2:2:-1], range(4, -4, -2))
132+
133+
def test_slice_rev_stepped_range(self):
134+
r = range(8, -8, -2)
135+
self.assertRangesEqual(r[:], range(8, -8, -2))
136+
self.assertRangesEqual(r[:2], range(8, 4, -2))
137+
self.assertRangesEqual(r[:-2], range(8, -4, -2))
138+
self.assertRangesEqual(r[2:], range(4, -8, -2))
139+
self.assertRangesEqual(r[-2:], range(-4, -8, -2))
140+
self.assertRangesEqual(r[2:-2], range(4, -4, -2))
141+
142+
def test_rev_slice_rev_stepped_range(self):
143+
r = range(8, -8, -2)
144+
self.assertRangesEqual(r[::-1], range(-6, 10, 2))
145+
self.assertRangesEqual(r[:2:-1], range(-6, 4, 2))
146+
self.assertRangesEqual(r[:-2:-1], range(-6, -4, 2))
147+
self.assertRangesEqual(r[2::-1], range(4, 10, 2))
148+
self.assertRangesEqual(r[-2::-1], range(-4, 10, 2))
149+
self.assertRangesEqual(r[-2:2:-1], range(-4, 4, 2))
76150

77151
def test_stepped_slice_stepped_range(self):
78-
r = range(0, 16, 2)
79-
self.assertEqual(r[::2], range(0, 16, 4))
80-
self.assertEqual(r[:2:2], range(0, 4, 4))
81-
self.assertEqual(r[:-2:2], range(0, 12, 4))
82-
self.assertEqual(r[2::2], range(4, 16, 4))
83-
self.assertEqual(r[-2::2], range(12, 16, 4))
84-
self.assertEqual(r[2:-2:2], range(4, 12, 4))
85-
86-
def test_rev_slice_range(self):
87-
r = range(8)
88-
self.assertEqual(r[::-1], range(7, -1, -1))
89-
self.assertEqual(r[:2:-1], range(7, 2, -1))
90-
self.assertEqual(r[:-2:-1], range(7, 6, -1))
91-
self.assertEqual(r[2::-1], range(2, -1, -1))
92-
self.assertEqual(r[-2::-1], range(6, -1, -1))
93-
self.assertEqual(r[-2:2:-1], range(6, 2, -1))
94-
r = range(0, 16, 2)
95-
self.assertEqual(r[::-2], range(14, -2, -4))
96-
self.assertEqual(r[:2:-2], range(14, 4, -4))
97-
self.assertEqual(r[:-2:-2], range(14, 12, -4))
98-
self.assertEqual(r[2::-2], range(4, -2, -4))
99-
self.assertEqual(r[-2::-2], range(12, -2, -4))
100-
self.assertEqual(r[-2:2:-2], range(12, 4, -4))
152+
r = range(-8, 8, 2)
153+
self.assertRangesEqual(r[::2], range(-8, 8, 4))
154+
self.assertRangesEqual(r[:2:2], range(-8, -4, 4))
155+
self.assertRangesEqual(r[:-2:2], range(-8, 4, 4))
156+
self.assertRangesEqual(r[2::2], range(-4, 8, 4))
157+
self.assertRangesEqual(r[-2::2], range(4, 8, 4))
158+
self.assertRangesEqual(r[2:-2:2], range(-4, 4, 4))
159+
160+
def test_rev_stepped_slice_stepped_range(self):
161+
r = range(-8, 8, 2)
162+
self.assertRangesEqual(r[::-2], range(6, -10, -4))
163+
self.assertRangesEqual(r[:2:-2], range(6, -4, -4))
164+
self.assertRangesEqual(r[:-2:-2], range(6, 4, -4))
165+
self.assertRangesEqual(r[2::-2], range(-4, -10, -4))
166+
self.assertRangesEqual(r[-2::-2], range(4, -10, -4))
167+
self.assertRangesEqual(r[-2:2:-2], range(4, -4, -4))
168+
169+
def test_stepped_slice_rev_stepped_range(self):
170+
r = range(8, -8, -2)
171+
self.assertRangesEqual(r[::2], range(8, -8, -4))
172+
self.assertRangesEqual(r[:2:2], range(8, 4, -4))
173+
self.assertRangesEqual(r[:-2:2], range(8, -4, -4))
174+
self.assertRangesEqual(r[2::2], range(4, -8, -4))
175+
self.assertRangesEqual(r[-2::2], range(-4, -8, -4))
176+
self.assertRangesEqual(r[2:-2:2], range(4, -4, -4))
177+
178+
def test_rev_stepped_slice_rev_stepped_range(self):
179+
r = range(8, -8, -2)
180+
self.assertRangesEqual(r[::-2], range(-6, 10, 4))
181+
self.assertRangesEqual(r[:2:-2], range(-6, 4, 4))
182+
self.assertRangesEqual(r[:-2:-2], range(-6, -4, 4))
183+
self.assertRangesEqual(r[2::-2], range(4, 10, 4))
184+
self.assertRangesEqual(r[-2::-2], range(-4, 10, 4))
185+
self.assertRangesEqual(r[-2:2:-2], range(-4, 4, 4))
101186

102187
def test_slice_zero_step(self):
103188
msg = '^slice step cannot be zero$'

0 commit comments

Comments
 (0)