blob: 914dd4c50d219a775db13ae25cc3d683e6890cd3 [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
Walter Dörwald67d99932007-05-20 08:22:37 +000093 def test_repr(self):
Walter Dörwald03b43d82007-05-21 10:43:34 +000094 self.assertEqual(repr(range(1)), 'range(0, 1)')
Walter Dörwald67d99932007-05-20 08:22:37 +000095 self.assertEqual(repr(range(1, 2)), 'range(1, 2)')
96 self.assertEqual(repr(range(1, 2, 3)), 'range(1, 2, 3)')
97
Alexandre Vassalotti75056072008-06-10 04:03:04 +000098 def test_pickling(self):
99 testcases = [(13,), (0, 11), (-22, 10), (20, 3, -1),
100 (13, 21, 3), (-2, 2, 2)]
Hirokazu Yamamotod0d0b652008-10-23 00:38:15 +0000101 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
Alexandre Vassalotti75056072008-06-10 04:03:04 +0000102 for t in testcases:
103 r = range(*t)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000104 self.assertEqual(list(pickle.loads(pickle.dumps(r, proto))),
105 list(r))
Alexandre Vassalotti75056072008-06-10 04:03:04 +0000106
Raymond Hettinger94f55832009-06-12 18:40:16 +0000107 def test_odd_bug(self):
108 # This used to raise a "SystemError: NULL result without error"
109 # because the range validation step was eating the exception
110 # before NULL was returned.
111 with self.assertRaises(TypeError):
112 range([], 1, -1)
113
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000114 def test_types(self):
115 # Non-integer objects *equal* to any of the range's items are supposed
116 # to be contained in the range.
Benjamin Peterson577473f2010-01-19 00:09:57 +0000117 self.assertIn(1.0, range(3))
118 self.assertIn(True, range(3))
119 self.assertIn(1+0j, range(3))
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000120
121 class C1:
122 def __eq__(self, other): return True
Benjamin Peterson577473f2010-01-19 00:09:57 +0000123 self.assertIn(C1(), range(3))
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000124
125 # Objects are never coerced into other types for comparison.
126 class C2:
127 def __int__(self): return 1
128 def __index__(self): return 1
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000129 self.assertNotIn(C2(), range(3))
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000130 # ..except if explicitly told so.
Benjamin Peterson577473f2010-01-19 00:09:57 +0000131 self.assertIn(int(C2()), range(3))
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000132
Mark Dickinson418f81d2009-09-24 20:04:23 +0000133 # Check that the range.__contains__ optimization is only
134 # used for ints, not for instances of subclasses of int.
135 class C3(int):
136 def __eq__(self, other): return True
Benjamin Peterson577473f2010-01-19 00:09:57 +0000137 self.assertIn(C3(11), range(10))
138 self.assertIn(C3(11), list(range(10)))
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000139
140 def test_strided_limits(self):
141 r = range(0, 101, 2)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000142 self.assertIn(0, r)
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000143 self.assertNotIn(1, r)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000144 self.assertIn(2, r)
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000145 self.assertNotIn(99, r)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000146 self.assertIn(100, r)
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000147 self.assertNotIn(101, r)
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000148
149 r = range(0, -20, -1)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000150 self.assertIn(0, r)
151 self.assertIn(-1, r)
152 self.assertIn(-19, r)
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000153 self.assertNotIn(-20, r)
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000154
155 r = range(0, -20, -2)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000156 self.assertIn(-18, r)
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000157 self.assertNotIn(-19, r)
158 self.assertNotIn(-20, r)
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000159
160 def test_empty(self):
161 r = range(0)
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000162 self.assertNotIn(0, r)
163 self.assertNotIn(1, r)
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000164
165 r = range(0, -10)
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000166 self.assertNotIn(0, r)
167 self.assertNotIn(-1, r)
168 self.assertNotIn(1, r)
Mark Dickinson3e124ae2009-09-22 21:47:24 +0000169
Mark Dickinsond550c9a2009-11-15 09:57:26 +0000170 def test_range_iterators(self):
171 # exercise 'fast' iterators, that use a rangeiterobject internally.
172 # see issue 7298
173 limits = [base + jiggle
174 for M in (2**32, 2**64)
175 for base in (-M, -M//2, 0, M//2, M)
176 for jiggle in (-2, -1, 0, 1, 2)]
177 test_ranges = [(start, end, step)
178 for start in limits
179 for end in limits
180 for step in (-2**63, -2**31, -2, -1, 1, 2)]
181
182 for start, end, step in test_ranges:
183 iter1 = range(start, end, step)
184 iter2 = pyrange(start, end, step)
185 test_id = "range({}, {}, {})".format(start, end, step)
186 # check first 100 entries
187 self.assert_iterators_equal(iter1, iter2, test_id, limit=100)
188
189 iter1 = reversed(range(start, end, step))
190 iter2 = pyrange_reversed(start, end, step)
191 test_id = "reversed(range({}, {}, {}))".format(start, end, step)
192 self.assert_iterators_equal(iter1, iter2, test_id, limit=100)
193
Neal Norwitz1c0423a2004-07-08 01:59:55 +0000194def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000195 test.support.run_unittest(RangeTest)
Neal Norwitz1c0423a2004-07-08 01:59:55 +0000196
197if __name__ == "__main__":
198 test_main()