blob: 5cbc11bf2184869f9abb60ca37d0dc89ce3138dd [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
139 self.assertRaises(OverflowError, len, range(0, sys.maxsize**10))
140
141 def test_invalid_invocation(self):
142 self.assertRaises(TypeError, range)
143 self.assertRaises(TypeError, range, 1, 2, 3, 4)
144 self.assertRaises(ValueError, range, 1, 2, 0)
Benjamin Petersond57bb552010-11-20 23:03:34 +0000145 a = int(10 * sys.maxsize)
Benjamin Peterson8d16ab32010-11-20 23:01:55 +0000146 self.assertRaises(ValueError, range, a, a + 1, int(0))
147 self.assertRaises(TypeError, range, 1., 1., 1.)
148 self.assertRaises(TypeError, range, 1e100, 1e101, 1e101)
149 self.assertRaises(TypeError, range, 0, "spam")
150 self.assertRaises(TypeError, range, 0, 42, "spam")
151 # Exercise various combinations of bad arguments, to check
152 # refcounting logic
153 self.assertRaises(TypeError, range, 0.0)
154 self.assertRaises(TypeError, range, 0, 0.0)
155 self.assertRaises(TypeError, range, 0.0, 0)
156 self.assertRaises(TypeError, range, 0.0, 0.0)
157 self.assertRaises(TypeError, range, 0, 0, 1.0)
158 self.assertRaises(TypeError, range, 0, 0.0, 1)
159 self.assertRaises(TypeError, range, 0, 0.0, 1.0)
160 self.assertRaises(TypeError, range, 0.0, 0, 1)
161 self.assertRaises(TypeError, range, 0.0, 0, 1.0)
162 self.assertRaises(TypeError, range, 0.0, 0.0, 1)
163 self.assertRaises(TypeError, range, 0.0, 0.0, 1.0)
164
165 def test_index(self):
166 u = range(2)
167 self.assertEqual(u.index(0), 0)
168 self.assertEqual(u.index(1), 1)
169 self.assertRaises(ValueError, u.index, 2)
170
171 u = range(-2, 3)
172 self.assertEqual(u.count(0), 1)
173 self.assertEqual(u.index(0), 2)
174 self.assertRaises(TypeError, u.index)
175
176 class BadExc(Exception):
177 pass
178
179 class BadCmp:
180 def __eq__(self, other):
181 if other == 2:
182 raise BadExc()
183 return False
184
185 a = range(4)
186 self.assertRaises(BadExc, a.index, BadCmp())
187
188 a = range(-2, 3)
189 self.assertEqual(a.index(0), 2)
190 self.assertEqual(range(1, 10, 3).index(4), 1)
191 self.assertEqual(range(1, -10, -3).index(-5), 2)
192
193 self.assertEqual(range(10**20).index(1), 1)
194 self.assertEqual(range(10**20).index(10**20 - 1), 10**20 - 1)
195
196 self.assertRaises(ValueError, range(1, 2**100, 2).index, 2**87)
197 self.assertEqual(range(1, 2**100, 2).index(2**87+1), 2**86)
198
199 class AlwaysEqual(object):
200 def __eq__(self, other):
201 return True
202 always_equal = AlwaysEqual()
Benjamin Petersond57bb552010-11-20 23:03:34 +0000203 self.assertEqual(range(10).index(always_equal), 0)
Benjamin Peterson8d16ab32010-11-20 23:01:55 +0000204
205 def test_user_index_method(self):
206 bignum = 2*sys.maxsize
207 smallnum = 42
208
209 # User-defined class with an __index__ method
210 class I:
211 def __init__(self, n):
212 self.n = int(n)
213 def __index__(self):
214 return self.n
215 self.assertEqual(list(range(I(bignum), I(bignum + 1))), [bignum])
216 self.assertEqual(list(range(I(smallnum), I(smallnum + 1))), [smallnum])
217
218 # User-defined class with a failing __index__ method
219 class IX:
220 def __index__(self):
221 raise RuntimeError
222 self.assertRaises(RuntimeError, range, IX())
223
224 # User-defined class with an invalid __index__ method
225 class IN:
226 def __index__(self):
227 return "not a number"
228
229 self.assertRaises(TypeError, range, IN())
230
231 def test_count(self):
232 self.assertEqual(range(3).count(-1), 0)
233 self.assertEqual(range(3).count(0), 1)
234 self.assertEqual(range(3).count(1), 1)
235 self.assertEqual(range(3).count(2), 1)
236 self.assertEqual(range(3).count(3), 0)
237 self.assertIs(type(range(3).count(-1)), int)
238 self.assertIs(type(range(3).count(1)), int)
239 self.assertEqual(range(10**20).count(1), 1)
240 self.assertEqual(range(10**20).count(10**20), 0)
241 self.assertEqual(range(3).index(1), 1)
242 self.assertEqual(range(1, 2**100, 2).count(2**87), 0)
243 self.assertEqual(range(1, 2**100, 2).count(2**87+1), 1)
244
245 class AlwaysEqual(object):
246 def __eq__(self, other):
247 return True
248 always_equal = AlwaysEqual()
249 self.assertEqual(range(10).count(always_equal), 10)
250
Walter Dörwald67d99932007-05-20 08:22:37 +0000251 def test_repr(self):
Walter Dörwald03b43d82007-05-21 10:43:34 +0000252 self.assertEqual(repr(range(1)), 'range(0, 1)')
Walter Dörwald67d99932007-05-20 08:22:37 +0000253 self.assertEqual(repr(range(1, 2)), 'range(1, 2)')
254 self.assertEqual(repr(range(1, 2, 3)), 'range(1, 2, 3)')
255
Alexandre Vassalotti75056072008-06-10 04:03:04 +0000256 def test_pickling(self):
257 testcases = [(13,), (0, 11), (-22, 10), (20, 3, -1),
258 (13, 21, 3), (-2, 2, 2)]
Hirokazu Yamamotod0d0b652008-10-23 00:38:15 +0000259 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
Alexandre Vassalotti75056072008-06-10 04:03:04 +0000260 for t in testcases:
261 r = range(*t)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000262 self.assertEqual(list(pickle.loads(pickle.dumps(r, proto))),
263 list(r))
Alexandre Vassalotti75056072008-06-10 04:03:04 +0000264
Raymond Hettinger94f55832009-06-12 18:40:16 +0000265 def test_odd_bug(self):
266 # This used to raise a "SystemError: NULL result without error"
267 # because the range validation step was eating the exception
268 # before NULL was returned.
269 with self.assertRaises(TypeError):
270 range([], 1, -1)
271
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000272 def test_types(self):
273 # Non-integer objects *equal* to any of the range's items are supposed
274 # to be contained in the range.
Benjamin Peterson577473f2010-01-19 00:09:57 +0000275 self.assertIn(1.0, range(3))
276 self.assertIn(True, range(3))
277 self.assertIn(1+0j, range(3))
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000278
279 class C1:
280 def __eq__(self, other): return True
Benjamin Peterson577473f2010-01-19 00:09:57 +0000281 self.assertIn(C1(), range(3))
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000282
283 # Objects are never coerced into other types for comparison.
284 class C2:
285 def __int__(self): return 1
286 def __index__(self): return 1
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000287 self.assertNotIn(C2(), range(3))
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000288 # ..except if explicitly told so.
Benjamin Peterson577473f2010-01-19 00:09:57 +0000289 self.assertIn(int(C2()), range(3))
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000290
Mark Dickinson418f81d2009-09-24 20:04:23 +0000291 # Check that the range.__contains__ optimization is only
292 # used for ints, not for instances of subclasses of int.
293 class C3(int):
294 def __eq__(self, other): return True
Benjamin Peterson577473f2010-01-19 00:09:57 +0000295 self.assertIn(C3(11), range(10))
296 self.assertIn(C3(11), list(range(10)))
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000297
298 def test_strided_limits(self):
299 r = range(0, 101, 2)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000300 self.assertIn(0, r)
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000301 self.assertNotIn(1, r)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000302 self.assertIn(2, r)
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000303 self.assertNotIn(99, r)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000304 self.assertIn(100, r)
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000305 self.assertNotIn(101, r)
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000306
307 r = range(0, -20, -1)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000308 self.assertIn(0, r)
309 self.assertIn(-1, r)
310 self.assertIn(-19, r)
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000311 self.assertNotIn(-20, r)
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000312
313 r = range(0, -20, -2)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000314 self.assertIn(-18, r)
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000315 self.assertNotIn(-19, r)
316 self.assertNotIn(-20, r)
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000317
318 def test_empty(self):
319 r = range(0)
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000320 self.assertNotIn(0, r)
321 self.assertNotIn(1, r)
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000322
323 r = range(0, -10)
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000324 self.assertNotIn(0, r)
325 self.assertNotIn(-1, r)
326 self.assertNotIn(1, r)
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000327
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000328 def test_range_iterators(self):
329 # exercise 'fast' iterators, that use a rangeiterobject internally.
330 # see issue 7298
331 limits = [base + jiggle
332 for M in (2**32, 2**64)
333 for base in (-M, -M//2, 0, M//2, M)
334 for jiggle in (-2, -1, 0, 1, 2)]
335 test_ranges = [(start, end, step)
336 for start in limits
337 for end in limits
338 for step in (-2**63, -2**31, -2, -1, 1, 2)]
339
340 for start, end, step in test_ranges:
341 iter1 = range(start, end, step)
342 iter2 = pyrange(start, end, step)
343 test_id = "range({}, {}, {})".format(start, end, step)
344 # check first 100 entries
345 self.assert_iterators_equal(iter1, iter2, test_id, limit=100)
346
347 iter1 = reversed(range(start, end, step))
348 iter2 = pyrange_reversed(start, end, step)
349 test_id = "reversed(range({}, {}, {}))".format(start, end, step)
350 self.assert_iterators_equal(iter1, iter2, test_id, limit=100)
351
Neal Norwitz1c0423a2004-07-08 01:59:55 +0000352def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000353 test.support.run_unittest(RangeTest)
Neal Norwitz1c0423a2004-07-08 01:59:55 +0000354
355if __name__ == "__main__":
356 test_main()