blob: 8e654772d952e245df0178752b9e8c94ad9d8227 [file] [log] [blame]
Neal Norwitz1c0423a2004-07-08 01:59:55 +00001# Python test set -- built-in functions
2
3import test.test_support, unittest
4import sys
Alexandre Vassalotti602d8db2008-06-10 04:01:23 +00005import pickle
Mark Dickinson009ae862009-11-15 12:31:13 +00006import itertools
Neal Norwitz1c0423a2004-07-08 01:59:55 +00007
8import warnings
9warnings.filterwarnings("ignore", "integer argument expected",
10 DeprecationWarning, "unittest")
11
Mark Dickinson009ae862009-11-15 12:31:13 +000012# pure Python implementations (3 args only), for comparison
13def pyrange(start, stop, step):
14 if (start - stop) // step < 0:
15 # replace stop with next element in the sequence of integers
16 # that are congruent to start modulo step.
17 stop += (start - stop) % step
18 while start != stop:
19 yield start
20 start += step
21
22def pyrange_reversed(start, stop, step):
23 stop += (start - stop) % step
24 return pyrange(stop - step, start - step, -step)
25
26
Neal Norwitz1c0423a2004-07-08 01:59:55 +000027class XrangeTest(unittest.TestCase):
Mark Dickinson009ae862009-11-15 12:31:13 +000028 def assert_iterators_equal(self, xs, ys, test_id, limit=None):
29 # check that an iterator xs matches the expected results ys,
30 # up to a given limit.
31 if limit is not None:
32 xs = itertools.islice(xs, limit)
33 ys = itertools.islice(ys, limit)
34 sentinel = object()
35 pairs = itertools.izip_longest(xs, ys, fillvalue=sentinel)
36 for i, (x, y) in enumerate(pairs):
37 if x == y:
38 continue
39 elif x == sentinel:
40 self.fail('{}: iterator ended unexpectedly '
41 'at position {}; expected {}'.format(test_id, i, y))
42 elif y == sentinel:
43 self.fail('{}: unexpected excess element {} at '
44 'position {}'.format(test_id, x, i))
45 else:
46 self.fail('{}: wrong element at position {};'
47 'expected {}, got {}'.format(test_id, i, y, x))
48
Neal Norwitz1c0423a2004-07-08 01:59:55 +000049 def test_xrange(self):
50 self.assertEqual(list(xrange(3)), [0, 1, 2])
51 self.assertEqual(list(xrange(1, 5)), [1, 2, 3, 4])
52 self.assertEqual(list(xrange(0)), [])
53 self.assertEqual(list(xrange(-3)), [])
54 self.assertEqual(list(xrange(1, 10, 3)), [1, 4, 7])
55 self.assertEqual(list(xrange(5, -5, -3)), [5, 2, -1, -4])
56
57 a = 10
58 b = 100
59 c = 50
60
61 self.assertEqual(list(xrange(a, a+2)), [a, a+1])
62 self.assertEqual(list(xrange(a+2, a, -1L)), [a+2, a+1])
63 self.assertEqual(list(xrange(a+4, a, -2)), [a+4, a+2])
64
65 seq = list(xrange(a, b, c))
Benjamin Peterson5c8da862009-06-30 22:57:08 +000066 self.assertTrue(a in seq)
67 self.assertTrue(b not in seq)
Neal Norwitz1c0423a2004-07-08 01:59:55 +000068 self.assertEqual(len(seq), 2)
69
70 seq = list(xrange(b, a, -c))
Benjamin Peterson5c8da862009-06-30 22:57:08 +000071 self.assertTrue(b in seq)
72 self.assertTrue(a not in seq)
Neal Norwitz1c0423a2004-07-08 01:59:55 +000073 self.assertEqual(len(seq), 2)
74
75 seq = list(xrange(-a, -b, -c))
Benjamin Peterson5c8da862009-06-30 22:57:08 +000076 self.assertTrue(-a in seq)
77 self.assertTrue(-b not in seq)
Neal Norwitz1c0423a2004-07-08 01:59:55 +000078 self.assertEqual(len(seq), 2)
79
80 self.assertRaises(TypeError, xrange)
81 self.assertRaises(TypeError, xrange, 1, 2, 3, 4)
82 self.assertRaises(ValueError, xrange, 1, 2, 0)
83
84 self.assertRaises(OverflowError, xrange, 1e100, 1e101, 1e101)
85
86 self.assertRaises(TypeError, xrange, 0, "spam")
87 self.assertRaises(TypeError, xrange, 0, 42, "spam")
88
Tim Petersfeec4532004-08-08 07:17:39 +000089 self.assertEqual(len(xrange(0, sys.maxint, sys.maxint-1)), 2)
90
Neal Norwitz1c0423a2004-07-08 01:59:55 +000091 self.assertRaises(OverflowError, xrange, -sys.maxint, sys.maxint)
92 self.assertRaises(OverflowError, xrange, 0, 2*sys.maxint)
93
Neal Norwitz64fa74d2004-10-14 03:46:18 +000094 r = xrange(-sys.maxint, sys.maxint, 2)
Thomas Woutersf4d8f392006-04-04 17:28:12 +000095 self.assertEqual(len(r), sys.maxint)
Tim Petersfeec4532004-08-08 07:17:39 +000096 self.assertRaises(OverflowError, xrange, -sys.maxint-1, sys.maxint, 2)
97
Alexandre Vassalotti602d8db2008-06-10 04:01:23 +000098 def test_pickling(self):
99 testcases = [(13,), (0, 11), (-22, 10), (20, 3, -1),
100 (13, 21, 3), (-2, 2, 2)]
Hirokazu Yamamoto592c2752008-10-23 00:37:33 +0000101 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
Alexandre Vassalotti602d8db2008-06-10 04:01:23 +0000102 for t in testcases:
103 r = xrange(*t)
104 self.assertEquals(list(pickle.loads(pickle.dumps(r, proto))),
105 list(r))
106
Mark Dickinson009ae862009-11-15 12:31:13 +0000107 def test_range_iterators(self):
108 # see issue 7298
109 limits = [base + jiggle
110 for M in (2**32, 2**64)
111 for base in (-M, -M//2, 0, M//2, M)
112 for jiggle in (-2, -1, 0, 1, 2)]
113 test_ranges = [(start, end, step)
114 for start in limits
115 for end in limits
116 for step in (-2**63, -2**31, -2, -1, 1, 2)]
117
118 for start, end, step in test_ranges:
119 try:
120 iter1 = xrange(start, end, step)
121 except OverflowError:
122 pass
123 else:
124 iter2 = pyrange(start, end, step)
125 test_id = "xrange({}, {}, {})".format(start, end, step)
126 # check first 100 entries
127 self.assert_iterators_equal(iter1, iter2, test_id, limit=100)
128
129 try:
130 iter1 = reversed(xrange(start, end, step))
131 except OverflowError:
132 pass
133 else:
134 iter2 = pyrange_reversed(start, end, step)
135 test_id = "reversed(xrange({}, {}, {}))".format(start, end, step)
136 self.assert_iterators_equal(iter1, iter2, test_id, limit=100)
137
Alexandre Vassalotti1f2f61a2008-06-10 03:34:53 +0000138
Neal Norwitz1c0423a2004-07-08 01:59:55 +0000139def test_main():
140 test.test_support.run_unittest(XrangeTest)
141
142if __name__ == "__main__":
143 test_main()