Skip to content

Commit e993b10

Browse files
committed
Issue 10889: Support slicing and indexing of large ranges (no docs changes, since, as far as I know, we never said anywhere that this *didn't* work)
1 parent b436b6c commit e993b10

2 files changed

Lines changed: 392 additions & 74 deletions

File tree

Lib/test/test_range.py

Lines changed: 86 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -125,23 +125,102 @@ def test_large_operands(self):
125125
self.assertIn(a, seq)
126126
self.assertNotIn(b, seq)
127127
self.assertEqual(len(seq), 2)
128+
self.assertEqual(seq[0], a)
129+
self.assertEqual(seq[-1], a+c)
128130

129131
seq = list(range(b, a, -c))
130132
self.assertIn(b, seq)
131133
self.assertNotIn(a, seq)
132134
self.assertEqual(len(seq), 2)
135+
self.assertEqual(seq[0], b)
136+
self.assertEqual(seq[-1], b-c)
133137

134138
seq = list(range(-a, -b, -c))
135139
self.assertIn(-a, seq)
136140
self.assertNotIn(-b, seq)
137141
self.assertEqual(len(seq), 2)
138-
139-
self.assertRaises(OverflowError, len,
140-
range(-sys.maxsize, sys.maxsize))
141-
self.assertRaises(OverflowError, len,
142-
range(0, 2*sys.maxsize))
143-
self.assertRaises(OverflowError, len,
144-
range(0, sys.maxsize**10))
142+
self.assertEqual(seq[0], -a)
143+
self.assertEqual(seq[-1], -a-c)
144+
145+
def test_large_range(self):
146+
# Check long ranges (len > sys.maxsize)
147+
# len() is expected to fail due to limitations of the __len__ protocol
148+
def _range_len(x):
149+
try:
150+
length = len(x)
151+
except OverflowError:
152+
step = x[1] - x[0]
153+
length = 1 + ((x[-1] - x[0]) // step)
154+
return length
155+
a = -sys.maxsize
156+
b = sys.maxsize
157+
expected_len = b - a
158+
x = range(a, b)
159+
self.assertIn(a, x)
160+
self.assertNotIn(b, x)
161+
self.assertRaises(OverflowError, len, x)
162+
self.assertEqual(_range_len(x), expected_len)
163+
self.assertEqual(x[0], a)
164+
idx = sys.maxsize+1
165+
self.assertEqual(x[idx], a+idx)
166+
self.assertEqual(x[idx:idx+1][0], a+idx)
167+
with self.assertRaises(IndexError):
168+
x[-expected_len-1]
169+
with self.assertRaises(IndexError):
170+
x[expected_len]
171+
172+
a = 0
173+
b = 2 * sys.maxsize
174+
expected_len = b - a
175+
x = range(a, b)
176+
self.assertIn(a, x)
177+
self.assertNotIn(b, x)
178+
self.assertRaises(OverflowError, len, x)
179+
self.assertEqual(_range_len(x), expected_len)
180+
self.assertEqual(x[0], a)
181+
idx = sys.maxsize+1
182+
self.assertEqual(x[idx], a+idx)
183+
self.assertEqual(x[idx:idx+1][0], a+idx)
184+
with self.assertRaises(IndexError):
185+
x[-expected_len-1]
186+
with self.assertRaises(IndexError):
187+
x[expected_len]
188+
189+
a = 0
190+
b = sys.maxsize**10
191+
c = 2*sys.maxsize
192+
expected_len = 1 + (b - a) // c
193+
x = range(a, b, c)
194+
self.assertIn(a, x)
195+
self.assertNotIn(b, x)
196+
self.assertRaises(OverflowError, len, x)
197+
self.assertEqual(_range_len(x), expected_len)
198+
self.assertEqual(x[0], a)
199+
idx = sys.maxsize+1
200+
self.assertEqual(x[idx], a+(idx*c))
201+
self.assertEqual(x[idx:idx+1][0], a+(idx*c))
202+
with self.assertRaises(IndexError):
203+
x[-expected_len-1]
204+
with self.assertRaises(IndexError):
205+
x[expected_len]
206+
207+
a = sys.maxsize**10
208+
b = 0
209+
c = -2*sys.maxsize
210+
expected_len = 1 + (b - a) // c
211+
x = range(a, b, c)
212+
self.assertIn(a, x)
213+
self.assertNotIn(b, x)
214+
self.assertRaises(OverflowError, len, x)
215+
self.assertEqual(_range_len(x), expected_len)
216+
self.assertEqual(x[0], a)
217+
idx = sys.maxsize+1
218+
self.assertEqual(x[idx], a+(idx*c))
219+
self.assertEqual(x[idx:idx+1][0], a+(idx*c))
220+
with self.assertRaises(IndexError):
221+
x[-expected_len-1]
222+
with self.assertRaises(IndexError):
223+
x[expected_len]
145224

146225
def test_invalid_invocation(self):
147226
self.assertRaises(TypeError, range)

0 commit comments

Comments
 (0)