blob: 5aa592082cb375a6650f642695f9db607c9c34d9 [file] [log] [blame]
Neal Norwitz1c0423a2004-07-08 01:59:55 +00001# Python test set -- built-in functions
2
Benjamin Petersonee8712c2008-05-20 21:35:26 +00003import test.support, unittest
Neal Norwitz1c0423a2004-07-08 01:59:55 +00004import sys
Alexandre Vassalotti75056072008-06-10 04:03:04 +00005import pickle
Mark Dickinsond550c9a2009-11-15 09:57:26 +00006import itertools
Neal Norwitz1c0423a2004-07-08 01:59:55 +00007
Mark Dickinsond550c9a2009-11-15 09:57:26 +00008# pure Python implementations (3 args only), for comparison
9def pyrange(start, stop, step):
10 if (start - stop) // step < 0:
11 # replace stop with next element in the sequence of integers
12 # that are congruent to start modulo step.
13 stop += (start - stop) % step
14 while start != stop:
15 yield start
16 start += step
17
18def pyrange_reversed(start, stop, step):
19 stop += (start - stop) % step
20 return pyrange(stop - step, start - step, -step)
21
22
Walter Dörwald4ad94212007-05-21 18:01:17 +000023class RangeTest(unittest.TestCase):
Mark Dickinsond550c9a2009-11-15 09:57:26 +000024 def assert_iterators_equal(self, xs, ys, test_id, limit=None):
25 # check that an iterator xs matches the expected results ys,
26 # up to a given limit.
27 if limit is not None:
28 xs = itertools.islice(xs, limit)
29 ys = itertools.islice(ys, limit)
30 sentinel = object()
31 pairs = itertools.zip_longest(xs, ys, fillvalue=sentinel)
32 for i, (x, y) in enumerate(pairs):
33 if x == y:
34 continue
35 elif x == sentinel:
36 self.fail('{}: iterator ended unexpectedly '
37 'at position {}; expected {}'.format(test_id, i, y))
38 elif y == sentinel:
39 self.fail('{}: unexpected excess element {} at '
40 'position {}'.format(test_id, x, i))
41 else:
42 self.fail('{}: wrong element at position {};'
43 'expected {}, got {}'.format(test_id, i, y, x))
44
Walter Dörwald4ad94212007-05-21 18:01:17 +000045 def test_range(self):
Guido van Rossum805365e2007-05-07 22:24:25 +000046 self.assertEqual(list(range(3)), [0, 1, 2])
47 self.assertEqual(list(range(1, 5)), [1, 2, 3, 4])
48 self.assertEqual(list(range(0)), [])
49 self.assertEqual(list(range(-3)), [])
50 self.assertEqual(list(range(1, 10, 3)), [1, 4, 7])
51 self.assertEqual(list(range(5, -5, -3)), [5, 2, -1, -4])
Neal Norwitz1c0423a2004-07-08 01:59:55 +000052
53 a = 10
54 b = 100
55 c = 50
56
Guido van Rossum805365e2007-05-07 22:24:25 +000057 self.assertEqual(list(range(a, a+2)), [a, a+1])
58 self.assertEqual(list(range(a+2, a, -1)), [a+2, a+1])
59 self.assertEqual(list(range(a+4, a, -2)), [a+4, a+2])
Neal Norwitz1c0423a2004-07-08 01:59:55 +000060
Guido van Rossum805365e2007-05-07 22:24:25 +000061 seq = list(range(a, b, c))
Benjamin Peterson577473f2010-01-19 00:09:57 +000062 self.assertIn(a, seq)
63 self.assertNotIn(b, seq)
Neal Norwitz1c0423a2004-07-08 01:59:55 +000064 self.assertEqual(len(seq), 2)
65
Guido van Rossum805365e2007-05-07 22:24:25 +000066 seq = list(range(b, a, -c))
Benjamin Peterson577473f2010-01-19 00:09:57 +000067 self.assertIn(b, seq)
68 self.assertNotIn(a, seq)
Neal Norwitz1c0423a2004-07-08 01:59:55 +000069 self.assertEqual(len(seq), 2)
70
Guido van Rossum805365e2007-05-07 22:24:25 +000071 seq = list(range(-a, -b, -c))
Benjamin Peterson577473f2010-01-19 00:09:57 +000072 self.assertIn(-a, seq)
73 self.assertNotIn(-b, seq)
Neal Norwitz1c0423a2004-07-08 01:59:55 +000074 self.assertEqual(len(seq), 2)
75
Guido van Rossum805365e2007-05-07 22:24:25 +000076 self.assertRaises(TypeError, range)
77 self.assertRaises(TypeError, range, 1, 2, 3, 4)
78 self.assertRaises(ValueError, range, 1, 2, 0)
Neal Norwitz1c0423a2004-07-08 01:59:55 +000079
Guido van Rossum805365e2007-05-07 22:24:25 +000080 self.assertRaises(TypeError, range, 0.0, 2, 1)
81 self.assertRaises(TypeError, range, 1, 2.0, 1)
82 self.assertRaises(TypeError, range, 1, 2, 1.0)
83 self.assertRaises(TypeError, range, 1e100, 1e101, 1e101)
Neal Norwitz1c0423a2004-07-08 01:59:55 +000084
Guido van Rossum805365e2007-05-07 22:24:25 +000085 self.assertRaises(TypeError, range, 0, "spam")
86 self.assertRaises(TypeError, range, 0, 42, "spam")
Neal Norwitz1c0423a2004-07-08 01:59:55 +000087
Christian Heimesa37d4c62007-12-04 23:02:19 +000088 self.assertEqual(len(range(0, sys.maxsize, sys.maxsize-1)), 2)
Tim Petersfeec4532004-08-08 07:17:39 +000089
Christian Heimesa37d4c62007-12-04 23:02:19 +000090 r = range(-sys.maxsize, sys.maxsize, 2)
91 self.assertEqual(len(r), sys.maxsize)
Tim Petersfeec4532004-08-08 07:17:39 +000092
Benjamin Peterson8d16ab32010-11-20 23:01:55 +000093 def test_large_operands(self):
94 x = range(10**20, 10**20+10, 3)
95 self.assertEqual(len(x), 4)
96 self.assertEqual(len(list(x)), 4)
97
98 x = range(10**20+10, 10**20, 3)
99 self.assertEqual(len(x), 0)
100 self.assertEqual(len(list(x)), 0)
101
102 x = range(10**20, 10**20+10, -3)
103 self.assertEqual(len(x), 0)
104 self.assertEqual(len(list(x)), 0)
105
106 x = range(10**20+10, 10**20, -3)
107 self.assertEqual(len(x), 4)
108 self.assertEqual(len(list(x)), 4)
109
110 # Now test range() with longs
111 self.assertEqual(list(range(-2**100)), [])
112 self.assertEqual(list(range(0, -2**100)), [])
113 self.assertEqual(list(range(0, 2**100, -1)), [])
114 self.assertEqual(list(range(0, 2**100, -1)), [])
115
116 a = int(10 * sys.maxsize)
117 b = int(100 * sys.maxsize)
118 c = int(50 * sys.maxsize)
119
120 self.assertEqual(list(range(a, a+2)), [a, a+1])
121 self.assertEqual(list(range(a+2, a, -1)), [a+2, a+1])
122 self.assertEqual(list(range(a+4, a, -2)), [a+4, a+2])
123
124 seq = list(range(a, b, c))
125 self.assertIn(a, seq)
126 self.assertNotIn(b, seq)
127 self.assertEqual(len(seq), 2)
128
129 seq = list(range(b, a, -c))
130 self.assertIn(b, seq)
131 self.assertNotIn(a, seq)
132 self.assertEqual(len(seq), 2)
133
134 seq = list(range(-a, -b, -c))
135 self.assertIn(-a, seq)
136 self.assertNotIn(-b, seq)
137 self.assertEqual(len(seq), 2)
138
Nick Coghlan37ee8502010-12-03 14:26:13 +0000139 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))
Benjamin Peterson8d16ab32010-11-20 23:01:55 +0000145
146 def test_invalid_invocation(self):
147 self.assertRaises(TypeError, range)
148 self.assertRaises(TypeError, range, 1, 2, 3, 4)
149 self.assertRaises(ValueError, range, 1, 2, 0)
Benjamin Petersond57bb552010-11-20 23:03:34 +0000150 a = int(10 * sys.maxsize)
Benjamin Peterson8d16ab32010-11-20 23:01:55 +0000151 self.assertRaises(ValueError, range, a, a + 1, int(0))
152 self.assertRaises(TypeError, range, 1., 1., 1.)
153 self.assertRaises(TypeError, range, 1e100, 1e101, 1e101)
154 self.assertRaises(TypeError, range, 0, "spam")
155 self.assertRaises(TypeError, range, 0, 42, "spam")
156 # Exercise various combinations of bad arguments, to check
157 # refcounting logic
158 self.assertRaises(TypeError, range, 0.0)
159 self.assertRaises(TypeError, range, 0, 0.0)
160 self.assertRaises(TypeError, range, 0.0, 0)
161 self.assertRaises(TypeError, range, 0.0, 0.0)
162 self.assertRaises(TypeError, range, 0, 0, 1.0)
163 self.assertRaises(TypeError, range, 0, 0.0, 1)
164 self.assertRaises(TypeError, range, 0, 0.0, 1.0)
165 self.assertRaises(TypeError, range, 0.0, 0, 1)
166 self.assertRaises(TypeError, range, 0.0, 0, 1.0)
167 self.assertRaises(TypeError, range, 0.0, 0.0, 1)
168 self.assertRaises(TypeError, range, 0.0, 0.0, 1.0)
169
170 def test_index(self):
171 u = range(2)
172 self.assertEqual(u.index(0), 0)
173 self.assertEqual(u.index(1), 1)
174 self.assertRaises(ValueError, u.index, 2)
175
176 u = range(-2, 3)
177 self.assertEqual(u.count(0), 1)
178 self.assertEqual(u.index(0), 2)
179 self.assertRaises(TypeError, u.index)
180
181 class BadExc(Exception):
182 pass
183
184 class BadCmp:
185 def __eq__(self, other):
186 if other == 2:
187 raise BadExc()
188 return False
189
190 a = range(4)
191 self.assertRaises(BadExc, a.index, BadCmp())
192
193 a = range(-2, 3)
194 self.assertEqual(a.index(0), 2)
195 self.assertEqual(range(1, 10, 3).index(4), 1)
196 self.assertEqual(range(1, -10, -3).index(-5), 2)
197
198 self.assertEqual(range(10**20).index(1), 1)
199 self.assertEqual(range(10**20).index(10**20 - 1), 10**20 - 1)
200
201 self.assertRaises(ValueError, range(1, 2**100, 2).index, 2**87)
202 self.assertEqual(range(1, 2**100, 2).index(2**87+1), 2**86)
203
204 class AlwaysEqual(object):
205 def __eq__(self, other):
206 return True
207 always_equal = AlwaysEqual()
Benjamin Petersond57bb552010-11-20 23:03:34 +0000208 self.assertEqual(range(10).index(always_equal), 0)
Benjamin Peterson8d16ab32010-11-20 23:01:55 +0000209
210 def test_user_index_method(self):
211 bignum = 2*sys.maxsize
212 smallnum = 42
213
214 # User-defined class with an __index__ method
215 class I:
216 def __init__(self, n):
217 self.n = int(n)
218 def __index__(self):
219 return self.n
220 self.assertEqual(list(range(I(bignum), I(bignum + 1))), [bignum])
221 self.assertEqual(list(range(I(smallnum), I(smallnum + 1))), [smallnum])
222
223 # User-defined class with a failing __index__ method
224 class IX:
225 def __index__(self):
226 raise RuntimeError
227 self.assertRaises(RuntimeError, range, IX())
228
229 # User-defined class with an invalid __index__ method
230 class IN:
231 def __index__(self):
232 return "not a number"
233
234 self.assertRaises(TypeError, range, IN())
235
236 def test_count(self):
237 self.assertEqual(range(3).count(-1), 0)
238 self.assertEqual(range(3).count(0), 1)
239 self.assertEqual(range(3).count(1), 1)
240 self.assertEqual(range(3).count(2), 1)
241 self.assertEqual(range(3).count(3), 0)
242 self.assertIs(type(range(3).count(-1)), int)
243 self.assertIs(type(range(3).count(1)), int)
244 self.assertEqual(range(10**20).count(1), 1)
245 self.assertEqual(range(10**20).count(10**20), 0)
246 self.assertEqual(range(3).index(1), 1)
247 self.assertEqual(range(1, 2**100, 2).count(2**87), 0)
248 self.assertEqual(range(1, 2**100, 2).count(2**87+1), 1)
249
250 class AlwaysEqual(object):
251 def __eq__(self, other):
252 return True
253 always_equal = AlwaysEqual()
254 self.assertEqual(range(10).count(always_equal), 10)
255
Nick Coghlan37ee8502010-12-03 14:26:13 +0000256 self.assertEqual(len(range(sys.maxsize, sys.maxsize+10)), 10)
257
Walter Dörwald67d99932007-05-20 08:22:37 +0000258 def test_repr(self):
Walter Dörwald03b43d82007-05-21 10:43:34 +0000259 self.assertEqual(repr(range(1)), 'range(0, 1)')
Walter Dörwald67d99932007-05-20 08:22:37 +0000260 self.assertEqual(repr(range(1, 2)), 'range(1, 2)')
261 self.assertEqual(repr(range(1, 2, 3)), 'range(1, 2, 3)')
262
Alexandre Vassalotti75056072008-06-10 04:03:04 +0000263 def test_pickling(self):
264 testcases = [(13,), (0, 11), (-22, 10), (20, 3, -1),
265 (13, 21, 3), (-2, 2, 2)]
Hirokazu Yamamotod0d0b652008-10-23 00:38:15 +0000266 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
Alexandre Vassalotti75056072008-06-10 04:03:04 +0000267 for t in testcases:
268 r = range(*t)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000269 self.assertEqual(list(pickle.loads(pickle.dumps(r, proto))),
270 list(r))
Alexandre Vassalotti75056072008-06-10 04:03:04 +0000271
Raymond Hettinger94f55832009-06-12 18:40:16 +0000272 def test_odd_bug(self):
273 # This used to raise a "SystemError: NULL result without error"
274 # because the range validation step was eating the exception
275 # before NULL was returned.
276 with self.assertRaises(TypeError):
277 range([], 1, -1)
278
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000279 def test_types(self):
280 # Non-integer objects *equal* to any of the range's items are supposed
281 # to be contained in the range.
Benjamin Peterson577473f2010-01-19 00:09:57 +0000282 self.assertIn(1.0, range(3))
283 self.assertIn(True, range(3))
284 self.assertIn(1+0j, range(3))
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000285
286 class C1:
287 def __eq__(self, other): return True
Benjamin Peterson577473f2010-01-19 00:09:57 +0000288 self.assertIn(C1(), range(3))
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000289
290 # Objects are never coerced into other types for comparison.
291 class C2:
292 def __int__(self): return 1
293 def __index__(self): return 1
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000294 self.assertNotIn(C2(), range(3))
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000295 # ..except if explicitly told so.
Benjamin Peterson577473f2010-01-19 00:09:57 +0000296 self.assertIn(int(C2()), range(3))
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000297
Mark Dickinson418f81d2009-09-24 20:04:23 +0000298 # Check that the range.__contains__ optimization is only
299 # used for ints, not for instances of subclasses of int.
300 class C3(int):
301 def __eq__(self, other): return True
Benjamin Peterson577473f2010-01-19 00:09:57 +0000302 self.assertIn(C3(11), range(10))
303 self.assertIn(C3(11), list(range(10)))
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000304
305 def test_strided_limits(self):
306 r = range(0, 101, 2)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000307 self.assertIn(0, r)
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000308 self.assertNotIn(1, r)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000309 self.assertIn(2, r)
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000310 self.assertNotIn(99, r)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000311 self.assertIn(100, r)
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000312 self.assertNotIn(101, r)
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000313
314 r = range(0, -20, -1)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000315 self.assertIn(0, r)
316 self.assertIn(-1, r)
317 self.assertIn(-19, r)
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000318 self.assertNotIn(-20, r)
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000319
320 r = range(0, -20, -2)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000321 self.assertIn(-18, r)
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000322 self.assertNotIn(-19, r)
323 self.assertNotIn(-20, r)
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000324
325 def test_empty(self):
326 r = range(0)
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000327 self.assertNotIn(0, r)
328 self.assertNotIn(1, r)
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000329
330 r = range(0, -10)
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000331 self.assertNotIn(0, r)
332 self.assertNotIn(-1, r)
333 self.assertNotIn(1, r)
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000334
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000335 def test_range_iterators(self):
336 # exercise 'fast' iterators, that use a rangeiterobject internally.
337 # see issue 7298
338 limits = [base + jiggle
339 for M in (2**32, 2**64)
340 for base in (-M, -M//2, 0, M//2, M)
341 for jiggle in (-2, -1, 0, 1, 2)]
342 test_ranges = [(start, end, step)
343 for start in limits
344 for end in limits
345 for step in (-2**63, -2**31, -2, -1, 1, 2)]
346
347 for start, end, step in test_ranges:
348 iter1 = range(start, end, step)
349 iter2 = pyrange(start, end, step)
350 test_id = "range({}, {}, {})".format(start, end, step)
351 # check first 100 entries
352 self.assert_iterators_equal(iter1, iter2, test_id, limit=100)
353
354 iter1 = reversed(range(start, end, step))
355 iter2 = pyrange_reversed(start, end, step)
356 test_id = "reversed(range({}, {}, {}))".format(start, end, step)
357 self.assert_iterators_equal(iter1, iter2, test_id, limit=100)
358
Nick Coghlan37ee8502010-12-03 14:26:13 +0000359 def test_slice(self):
360 def check(start, stop, step=None):
361 i = slice(start, stop, step)
362 self.assertEqual(list(r[i]), list(r)[i])
363 self.assertEqual(len(r[i]), len(list(r)[i]))
364 for r in [range(10),
365 range(0),
366 range(1, 9, 3),
367 range(8, 0, -3),
368 range(sys.maxsize+1, sys.maxsize+10),
369 ]:
370 check(0, 2)
371 check(0, 20)
372 check(1, 2)
373 check(20, 30)
374 check(-30, -20)
375 check(-1, 100, 2)
376 check(0, -1)
377 check(-1, -3, -1)
378
379 def test_contains(self):
380 r = range(10)
381 self.assertIn(0, r)
382 self.assertIn(1, r)
383 self.assertIn(5.0, r)
384 self.assertNotIn(5.1, r)
385 self.assertNotIn(-1, r)
386 self.assertNotIn(10, r)
387 self.assertNotIn("", r)
388 r = range(9, -1, -1)
389 self.assertIn(0, r)
390 self.assertIn(1, r)
391 self.assertIn(5.0, r)
392 self.assertNotIn(5.1, r)
393 self.assertNotIn(-1, r)
394 self.assertNotIn(10, r)
395 self.assertNotIn("", r)
396 r = range(0, 10, 2)
397 self.assertIn(0, r)
398 self.assertNotIn(1, r)
399 self.assertNotIn(5.0, r)
400 self.assertNotIn(5.1, r)
401 self.assertNotIn(-1, r)
402 self.assertNotIn(10, r)
403 self.assertNotIn("", r)
404 r = range(9, -1, -2)
405 self.assertNotIn(0, r)
406 self.assertIn(1, r)
407 self.assertIn(5.0, r)
408 self.assertNotIn(5.1, r)
409 self.assertNotIn(-1, r)
410 self.assertNotIn(10, r)
411 self.assertNotIn("", r)
412
413 def test_reverse_iteration(self):
414 for r in [range(10),
415 range(0),
416 range(1, 9, 3),
417 range(8, 0, -3),
418 range(sys.maxsize+1, sys.maxsize+10),
419 ]:
420 self.assertEqual(list(reversed(r)), list(r)[::-1])
421
422
Neal Norwitz1c0423a2004-07-08 01:59:55 +0000423def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000424 test.support.run_unittest(RangeTest)
Neal Norwitz1c0423a2004-07-08 01:59:55 +0000425
426if __name__ == "__main__":
427 test_main()