1# Python test set -- built-in functions
2
3import unittest
4import sys
5import pickle
6import itertools
7from test.support import ALWAYS_EQ
8
9# pure Python implementations (3 args only), for comparison
10def pyrange(start, stop, step):
11    if (start - stop) // step < 0:
12        # replace stop with next element in the sequence of integers
13        # that are congruent to start modulo step.
14        stop += (start - stop) % step
15        while start != stop:
16            yield start
17            start += step
18
19def pyrange_reversed(start, stop, step):
20    stop += (start - stop) % step
21    return pyrange(stop - step, start - step, -step)
22
23
24class RangeTest(unittest.TestCase):
25    def assert_iterators_equal(self, xs, ys, test_id, limit=None):
26        # check that an iterator xs matches the expected results ys,
27        # up to a given limit.
28        if limit is not None:
29            xs = itertools.islice(xs, limit)
30            ys = itertools.islice(ys, limit)
31        sentinel = object()
32        pairs = itertools.zip_longest(xs, ys, fillvalue=sentinel)
33        for i, (x, y) in enumerate(pairs):
34            if x == y:
35                continue
36            elif x == sentinel:
37                self.fail('{}: iterator ended unexpectedly '
38                          'at position {}; expected {}'.format(test_id, i, y))
39            elif y == sentinel:
40                self.fail('{}: unexpected excess element {} at '
41                          'position {}'.format(test_id, x, i))
42            else:
43                self.fail('{}: wrong element at position {}; '
44                          'expected {}, got {}'.format(test_id, i, y, x))
45
46    def test_range(self):
47        self.assertEqual(list(range(3)), [0, 1, 2])
48        self.assertEqual(list(range(1, 5)), [1, 2, 3, 4])
49        self.assertEqual(list(range(0)), [])
50        self.assertEqual(list(range(-3)), [])
51        self.assertEqual(list(range(1, 10, 3)), [1, 4, 7])
52        self.assertEqual(list(range(5, -5, -3)), [5, 2, -1, -4])
53
54        a = 10
55        b = 100
56        c = 50
57
58        self.assertEqual(list(range(a, a+2)), [a, a+1])
59        self.assertEqual(list(range(a+2, a, -1)), [a+2, a+1])
60        self.assertEqual(list(range(a+4, a, -2)), [a+4, a+2])
61
62        seq = list(range(a, b, c))
63        self.assertIn(a, seq)
64        self.assertNotIn(b, seq)
65        self.assertEqual(len(seq), 2)
66
67        seq = list(range(b, a, -c))
68        self.assertIn(b, seq)
69        self.assertNotIn(a, seq)
70        self.assertEqual(len(seq), 2)
71
72        seq = list(range(-a, -b, -c))
73        self.assertIn(-a, seq)
74        self.assertNotIn(-b, seq)
75        self.assertEqual(len(seq), 2)
76
77        self.assertRaises(TypeError, range)
78        self.assertRaises(TypeError, range, 1, 2, 3, 4)
79        self.assertRaises(ValueError, range, 1, 2, 0)
80
81        self.assertRaises(TypeError, range, 0.0, 2, 1)
82        self.assertRaises(TypeError, range, 1, 2.0, 1)
83        self.assertRaises(TypeError, range, 1, 2, 1.0)
84        self.assertRaises(TypeError, range, 1e100, 1e101, 1e101)
85
86        self.assertRaises(TypeError, range, 0, "spam")
87        self.assertRaises(TypeError, range, 0, 42, "spam")
88
89        self.assertEqual(len(range(0, sys.maxsize, sys.maxsize-1)), 2)
90
91        r = range(-sys.maxsize, sys.maxsize, 2)
92        self.assertEqual(len(r), sys.maxsize)
93
94    def test_range_constructor_error_messages(self):
95        with self.assertRaisesRegex(
96                TypeError,
97                "range expected at least 1 argument, got 0"
98        ):
99            range()
100
101        with self.assertRaisesRegex(
102                TypeError,
103                "range expected at most 3 arguments, got 6"
104        ):
105            range(1, 2, 3, 4, 5, 6)
106
107    def test_large_operands(self):
108        x = range(10**20, 10**20+10, 3)
109        self.assertEqual(len(x), 4)
110        self.assertEqual(len(list(x)), 4)
111
112        x = range(10**20+10, 10**20, 3)
113        self.assertEqual(len(x), 0)
114        self.assertEqual(len(list(x)), 0)
115        self.assertFalse(x)
116
117        x = range(10**20, 10**20+10, -3)
118        self.assertEqual(len(x), 0)
119        self.assertEqual(len(list(x)), 0)
120        self.assertFalse(x)
121
122        x = range(10**20+10, 10**20, -3)
123        self.assertEqual(len(x), 4)
124        self.assertEqual(len(list(x)), 4)
125        self.assertTrue(x)
126
127        # Now test range() with longs
128        for x in [range(-2**100),
129                  range(0, -2**100),
130                  range(0, 2**100, -1)]:
131            self.assertEqual(list(x), [])
132            self.assertFalse(x)
133
134        a = int(10 * sys.maxsize)
135        b = int(100 * sys.maxsize)
136        c = int(50 * sys.maxsize)
137
138        self.assertEqual(list(range(a, a+2)), [a, a+1])
139        self.assertEqual(list(range(a+2, a, -1)), [a+2, a+1])
140        self.assertEqual(list(range(a+4, a, -2)), [a+4, a+2])
141
142        seq = list(range(a, b, c))
143        self.assertIn(a, seq)
144        self.assertNotIn(b, seq)
145        self.assertEqual(len(seq), 2)
146        self.assertEqual(seq[0], a)
147        self.assertEqual(seq[-1], a+c)
148
149        seq = list(range(b, a, -c))
150        self.assertIn(b, seq)
151        self.assertNotIn(a, seq)
152        self.assertEqual(len(seq), 2)
153        self.assertEqual(seq[0], b)
154        self.assertEqual(seq[-1], b-c)
155
156        seq = list(range(-a, -b, -c))
157        self.assertIn(-a, seq)
158        self.assertNotIn(-b, seq)
159        self.assertEqual(len(seq), 2)
160        self.assertEqual(seq[0], -a)
161        self.assertEqual(seq[-1], -a-c)
162
163    def test_large_range(self):
164        # Check long ranges (len > sys.maxsize)
165        # len() is expected to fail due to limitations of the __len__ protocol
166        def _range_len(x):
167            try:
168                length = len(x)
169            except OverflowError:
170                step = x[1] - x[0]
171                length = 1 + ((x[-1] - x[0]) // step)
172            return length
173
174        a = -sys.maxsize
175        b = sys.maxsize
176        expected_len = b - a
177        x = range(a, b)
178        self.assertIn(a, x)
179        self.assertNotIn(b, x)
180        self.assertRaises(OverflowError, len, x)
181        self.assertTrue(x)
182        self.assertEqual(_range_len(x), expected_len)
183        self.assertEqual(x[0], a)
184        idx = sys.maxsize+1
185        self.assertEqual(x[idx], a+idx)
186        self.assertEqual(x[idx:idx+1][0], a+idx)
187        with self.assertRaises(IndexError):
188            x[-expected_len-1]
189        with self.assertRaises(IndexError):
190            x[expected_len]
191
192        a = 0
193        b = 2 * sys.maxsize
194        expected_len = b - a
195        x = range(a, b)
196        self.assertIn(a, x)
197        self.assertNotIn(b, x)
198        self.assertRaises(OverflowError, len, x)
199        self.assertTrue(x)
200        self.assertEqual(_range_len(x), expected_len)
201        self.assertEqual(x[0], a)
202        idx = sys.maxsize+1
203        self.assertEqual(x[idx], a+idx)
204        self.assertEqual(x[idx:idx+1][0], a+idx)
205        with self.assertRaises(IndexError):
206            x[-expected_len-1]
207        with self.assertRaises(IndexError):
208            x[expected_len]
209
210        a = 0
211        b = sys.maxsize**10
212        c = 2*sys.maxsize
213        expected_len = 1 + (b - a) // c
214        x = range(a, b, c)
215        self.assertIn(a, x)
216        self.assertNotIn(b, x)
217        self.assertRaises(OverflowError, len, x)
218        self.assertTrue(x)
219        self.assertEqual(_range_len(x), expected_len)
220        self.assertEqual(x[0], a)
221        idx = sys.maxsize+1
222        self.assertEqual(x[idx], a+(idx*c))
223        self.assertEqual(x[idx:idx+1][0], a+(idx*c))
224        with self.assertRaises(IndexError):
225            x[-expected_len-1]
226        with self.assertRaises(IndexError):
227            x[expected_len]
228
229        a = sys.maxsize**10
230        b = 0
231        c = -2*sys.maxsize
232        expected_len = 1 + (b - a) // c
233        x = range(a, b, c)
234        self.assertIn(a, x)
235        self.assertNotIn(b, x)
236        self.assertRaises(OverflowError, len, x)
237        self.assertTrue(x)
238        self.assertEqual(_range_len(x), expected_len)
239        self.assertEqual(x[0], a)
240        idx = sys.maxsize+1
241        self.assertEqual(x[idx], a+(idx*c))
242        self.assertEqual(x[idx:idx+1][0], a+(idx*c))
243        with self.assertRaises(IndexError):
244            x[-expected_len-1]
245        with self.assertRaises(IndexError):
246            x[expected_len]
247
248    def test_invalid_invocation(self):
249        self.assertRaises(TypeError, range)
250        self.assertRaises(TypeError, range, 1, 2, 3, 4)
251        self.assertRaises(ValueError, range, 1, 2, 0)
252        a = int(10 * sys.maxsize)
253        self.assertRaises(ValueError, range, a, a + 1, int(0))
254        self.assertRaises(TypeError, range, 1., 1., 1.)
255        self.assertRaises(TypeError, range, 1e100, 1e101, 1e101)
256        self.assertRaises(TypeError, range, 0, "spam")
257        self.assertRaises(TypeError, range, 0, 42, "spam")
258        # Exercise various combinations of bad arguments, to check
259        # refcounting logic
260        self.assertRaises(TypeError, range, 0.0)
261        self.assertRaises(TypeError, range, 0, 0.0)
262        self.assertRaises(TypeError, range, 0.0, 0)
263        self.assertRaises(TypeError, range, 0.0, 0.0)
264        self.assertRaises(TypeError, range, 0, 0, 1.0)
265        self.assertRaises(TypeError, range, 0, 0.0, 1)
266        self.assertRaises(TypeError, range, 0, 0.0, 1.0)
267        self.assertRaises(TypeError, range, 0.0, 0, 1)
268        self.assertRaises(TypeError, range, 0.0, 0, 1.0)
269        self.assertRaises(TypeError, range, 0.0, 0.0, 1)
270        self.assertRaises(TypeError, range, 0.0, 0.0, 1.0)
271
272    def test_index(self):
273        u = range(2)
274        self.assertEqual(u.index(0), 0)
275        self.assertEqual(u.index(1), 1)
276        self.assertRaises(ValueError, u.index, 2)
277
278        u = range(-2, 3)
279        self.assertEqual(u.count(0), 1)
280        self.assertEqual(u.index(0), 2)
281        self.assertRaises(TypeError, u.index)
282
283        class BadExc(Exception):
284            pass
285
286        class BadCmp:
287            def __eq__(self, other):
288                if other == 2:
289                    raise BadExc()
290                return False
291
292        a = range(4)
293        self.assertRaises(BadExc, a.index, BadCmp())
294
295        a = range(-2, 3)
296        self.assertEqual(a.index(0), 2)
297        self.assertEqual(range(1, 10, 3).index(4), 1)
298        self.assertEqual(range(1, -10, -3).index(-5), 2)
299
300        self.assertEqual(range(10**20).index(1), 1)
301        self.assertEqual(range(10**20).index(10**20 - 1), 10**20 - 1)
302
303        self.assertRaises(ValueError, range(1, 2**100, 2).index, 2**87)
304        self.assertEqual(range(1, 2**100, 2).index(2**87+1), 2**86)
305
306        self.assertEqual(range(10).index(ALWAYS_EQ), 0)
307
308    def test_user_index_method(self):
309        bignum = 2*sys.maxsize
310        smallnum = 42
311
312        # User-defined class with an __index__ method
313        class I:
314            def __init__(self, n):
315                self.n = int(n)
316            def __index__(self):
317                return self.n
318        self.assertEqual(list(range(I(bignum), I(bignum + 1))), [bignum])
319        self.assertEqual(list(range(I(smallnum), I(smallnum + 1))), [smallnum])
320
321        # User-defined class with a failing __index__ method
322        class IX:
323            def __index__(self):
324                raise RuntimeError
325        self.assertRaises(RuntimeError, range, IX())
326
327        # User-defined class with an invalid __index__ method
328        class IN:
329            def __index__(self):
330                return "not a number"
331
332        self.assertRaises(TypeError, range, IN())
333
334        # Test use of user-defined classes in slice indices.
335        self.assertEqual(range(10)[:I(5)], range(5))
336
337        with self.assertRaises(RuntimeError):
338            range(0, 10)[:IX()]
339
340        with self.assertRaises(TypeError):
341            range(0, 10)[:IN()]
342
343    def test_count(self):
344        self.assertEqual(range(3).count(-1), 0)
345        self.assertEqual(range(3).count(0), 1)
346        self.assertEqual(range(3).count(1), 1)
347        self.assertEqual(range(3).count(2), 1)
348        self.assertEqual(range(3).count(3), 0)
349        self.assertIs(type(range(3).count(-1)), int)
350        self.assertIs(type(range(3).count(1)), int)
351        self.assertEqual(range(10**20).count(1), 1)
352        self.assertEqual(range(10**20).count(10**20), 0)
353        self.assertEqual(range(3).index(1), 1)
354        self.assertEqual(range(1, 2**100, 2).count(2**87), 0)
355        self.assertEqual(range(1, 2**100, 2).count(2**87+1), 1)
356
357        self.assertEqual(range(10).count(ALWAYS_EQ), 10)
358
359        self.assertEqual(len(range(sys.maxsize, sys.maxsize+10)), 10)
360
361    def test_repr(self):
362        self.assertEqual(repr(range(1)), 'range(0, 1)')
363        self.assertEqual(repr(range(1, 2)), 'range(1, 2)')
364        self.assertEqual(repr(range(1, 2, 3)), 'range(1, 2, 3)')
365
366    def test_pickling(self):
367        testcases = [(13,), (0, 11), (-22, 10), (20, 3, -1),
368                     (13, 21, 3), (-2, 2, 2), (2**65, 2**65+2)]
369        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
370            for t in testcases:
371                with self.subTest(proto=proto, test=t):
372                    r = range(*t)
373                    self.assertEqual(list(pickle.loads(pickle.dumps(r, proto))),
374                                     list(r))
375
376    def test_iterator_pickling(self):
377        testcases = [(13,), (0, 11), (-22, 10), (20, 3, -1), (13, 21, 3),
378                     (-2, 2, 2)]
379        for M in 2**31, 2**63:
380            testcases += [
381                (M-3, M-1), (4*M, 4*M+2),
382                (M-2, M-1, 2), (-M+1, -M, -2),
383                (1, 2, M-1), (-1, -2, -M),
384                (1, M-1, M-1), (-1, -M, -M),
385            ]
386        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
387            for t in testcases:
388                with self.subTest(proto=proto, t=t):
389                    it = itorg = iter(range(*t))
390                    data = list(range(*t))
391
392                    d = pickle.dumps(it, proto)
393                    it = pickle.loads(d)
394                    self.assertEqual(type(itorg), type(it))
395                    self.assertEqual(list(it), data)
396
397                    it = pickle.loads(d)
398                    try:
399                        next(it)
400                    except StopIteration:
401                        continue
402                    d = pickle.dumps(it, proto)
403                    it = pickle.loads(d)
404                    self.assertEqual(list(it), data[1:])
405
406    def test_iterator_pickling_overflowing_index(self):
407        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
408            with self.subTest(proto=proto):
409                it = iter(range(2**32 + 2))
410                _, _, idx = it.__reduce__()
411                self.assertEqual(idx, 0)
412                it.__setstate__(2**32 + 1)  # undocumented way to set r->index
413                _, _, idx = it.__reduce__()
414                self.assertEqual(idx, 2**32 + 1)
415                d = pickle.dumps(it, proto)
416                it = pickle.loads(d)
417                self.assertEqual(next(it), 2**32 + 1)
418
419    def test_exhausted_iterator_pickling(self):
420        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
421            r = range(2**65, 2**65+2)
422            i = iter(r)
423            while True:
424                r = next(i)
425                if r == 2**65+1:
426                    break
427            d = pickle.dumps(i, proto)
428            i2 = pickle.loads(d)
429            self.assertEqual(list(i), [])
430            self.assertEqual(list(i2), [])
431
432    def test_large_exhausted_iterator_pickling(self):
433        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
434            r = range(20)
435            i = iter(r)
436            while True:
437                r = next(i)
438                if r == 19:
439                    break
440            d = pickle.dumps(i, proto)
441            i2 = pickle.loads(d)
442            self.assertEqual(list(i), [])
443            self.assertEqual(list(i2), [])
444
445    def test_odd_bug(self):
446        # This used to raise a "SystemError: NULL result without error"
447        # because the range validation step was eating the exception
448        # before NULL was returned.
449        with self.assertRaises(TypeError):
450            range([], 1, -1)
451
452    def test_types(self):
453        # Non-integer objects *equal* to any of the range's items are supposed
454        # to be contained in the range.
455        self.assertIn(1.0, range(3))
456        self.assertIn(True, range(3))
457        self.assertIn(1+0j, range(3))
458
459        self.assertIn(ALWAYS_EQ, range(3))
460
461        # Objects are never coerced into other types for comparison.
462        class C2:
463            def __int__(self): return 1
464            def __index__(self): return 1
465        self.assertNotIn(C2(), range(3))
466        # ..except if explicitly told so.
467        self.assertIn(int(C2()), range(3))
468
469        # Check that the range.__contains__ optimization is only
470        # used for ints, not for instances of subclasses of int.
471        class C3(int):
472            def __eq__(self, other): return True
473        self.assertIn(C3(11), range(10))
474        self.assertIn(C3(11), list(range(10)))
475
476    def test_strided_limits(self):
477        r = range(0, 101, 2)
478        self.assertIn(0, r)
479        self.assertNotIn(1, r)
480        self.assertIn(2, r)
481        self.assertNotIn(99, r)
482        self.assertIn(100, r)
483        self.assertNotIn(101, r)
484
485        r = range(0, -20, -1)
486        self.assertIn(0, r)
487        self.assertIn(-1, r)
488        self.assertIn(-19, r)
489        self.assertNotIn(-20, r)
490
491        r = range(0, -20, -2)
492        self.assertIn(-18, r)
493        self.assertNotIn(-19, r)
494        self.assertNotIn(-20, r)
495
496    def test_empty(self):
497        r = range(0)
498        self.assertNotIn(0, r)
499        self.assertNotIn(1, r)
500
501        r = range(0, -10)
502        self.assertNotIn(0, r)
503        self.assertNotIn(-1, r)
504        self.assertNotIn(1, r)
505
506    def test_range_iterators(self):
507        # exercise 'fast' iterators, that use a rangeiterobject internally.
508        # see issue 7298
509        limits = [base + jiggle
510                  for M in (2**32, 2**64)
511                  for base in (-M, -M//2, 0, M//2, M)
512                  for jiggle in (-2, -1, 0, 1, 2)]
513        test_ranges = [(start, end, step)
514                       for start in limits
515                       for end in limits
516                       for step in (-2**63, -2**31, -2, -1, 1, 2)]
517
518        for start, end, step in test_ranges:
519            iter1 = range(start, end, step)
520            iter2 = pyrange(start, end, step)
521            test_id = "range({}, {}, {})".format(start, end, step)
522            # check first 100 entries
523            self.assert_iterators_equal(iter1, iter2, test_id, limit=100)
524
525            iter1 = reversed(range(start, end, step))
526            iter2 = pyrange_reversed(start, end, step)
527            test_id = "reversed(range({}, {}, {}))".format(start, end, step)
528            self.assert_iterators_equal(iter1, iter2, test_id, limit=100)
529
530    def test_range_iterators_invocation(self):
531        # verify range iterators instances cannot be created by
532        # calling their type
533        rangeiter_type = type(iter(range(0)))
534        self.assertRaises(TypeError, rangeiter_type, 1, 3, 1)
535        long_rangeiter_type = type(iter(range(1 << 1000)))
536        self.assertRaises(TypeError, long_rangeiter_type, 1, 3, 1)
537
538    def test_slice(self):
539        def check(start, stop, step=None):
540            i = slice(start, stop, step)
541            self.assertEqual(list(r[i]), list(r)[i])
542            self.assertEqual(len(r[i]), len(list(r)[i]))
543        for r in [range(10),
544                  range(0),
545                  range(1, 9, 3),
546                  range(8, 0, -3),
547                  range(sys.maxsize+1, sys.maxsize+10),
548                  ]:
549            check(0, 2)
550            check(0, 20)
551            check(1, 2)
552            check(20, 30)
553            check(-30, -20)
554            check(-1, 100, 2)
555            check(0, -1)
556            check(-1, -3, -1)
557
558    def test_contains(self):
559        r = range(10)
560        self.assertIn(0, r)
561        self.assertIn(1, r)
562        self.assertIn(5.0, r)
563        self.assertNotIn(5.1, r)
564        self.assertNotIn(-1, r)
565        self.assertNotIn(10, r)
566        self.assertNotIn("", r)
567        r = range(9, -1, -1)
568        self.assertIn(0, r)
569        self.assertIn(1, r)
570        self.assertIn(5.0, r)
571        self.assertNotIn(5.1, r)
572        self.assertNotIn(-1, r)
573        self.assertNotIn(10, r)
574        self.assertNotIn("", r)
575        r = range(0, 10, 2)
576        self.assertIn(0, r)
577        self.assertNotIn(1, r)
578        self.assertNotIn(5.0, r)
579        self.assertNotIn(5.1, r)
580        self.assertNotIn(-1, r)
581        self.assertNotIn(10, r)
582        self.assertNotIn("", r)
583        r = range(9, -1, -2)
584        self.assertNotIn(0, r)
585        self.assertIn(1, r)
586        self.assertIn(5.0, r)
587        self.assertNotIn(5.1, r)
588        self.assertNotIn(-1, r)
589        self.assertNotIn(10, r)
590        self.assertNotIn("", r)
591
592    def test_reverse_iteration(self):
593        for r in [range(10),
594                  range(0),
595                  range(1, 9, 3),
596                  range(8, 0, -3),
597                  range(sys.maxsize+1, sys.maxsize+10),
598                  ]:
599            self.assertEqual(list(reversed(r)), list(r)[::-1])
600
601    def test_issue11845(self):
602        r = range(*slice(1, 18, 2).indices(20))
603        values = {None, 0, 1, -1, 2, -2, 5, -5, 19, -19,
604                  20, -20, 21, -21, 30, -30, 99, -99}
605        for i in values:
606            for j in values:
607                for k in values - {0}:
608                    r[i:j:k]
609
610    def test_comparison(self):
611        test_ranges = [range(0), range(0, -1), range(1, 1, 3),
612                       range(1), range(5, 6), range(5, 6, 2),
613                       range(5, 7, 2), range(2), range(0, 4, 2),
614                       range(0, 5, 2), range(0, 6, 2)]
615        test_tuples = list(map(tuple, test_ranges))
616
617        # Check that equality of ranges matches equality of the corresponding
618        # tuples for each pair from the test lists above.
619        ranges_eq = [a == b for a in test_ranges for b in test_ranges]
620        tuples_eq = [a == b for a in test_tuples for b in test_tuples]
621        self.assertEqual(ranges_eq, tuples_eq)
622
623        # Check that != correctly gives the logical negation of ==
624        ranges_ne = [a != b for a in test_ranges for b in test_ranges]
625        self.assertEqual(ranges_ne, [not x for x in ranges_eq])
626
627        # Equal ranges should have equal hashes.
628        for a in test_ranges:
629            for b in test_ranges:
630                if a == b:
631                    self.assertEqual(hash(a), hash(b))
632
633        # Ranges are unequal to other types (even sequence types)
634        self.assertIs(range(0) == (), False)
635        self.assertIs(() == range(0), False)
636        self.assertIs(range(2) == [0, 1], False)
637
638        # Huge integers aren't a problem.
639        self.assertEqual(range(0, 2**100 - 1, 2),
640                         range(0, 2**100, 2))
641        self.assertEqual(hash(range(0, 2**100 - 1, 2)),
642                         hash(range(0, 2**100, 2)))
643        self.assertNotEqual(range(0, 2**100, 2),
644                            range(0, 2**100 + 1, 2))
645        self.assertEqual(range(2**200, 2**201 - 2**99, 2**100),
646                         range(2**200, 2**201, 2**100))
647        self.assertEqual(hash(range(2**200, 2**201 - 2**99, 2**100)),
648                         hash(range(2**200, 2**201, 2**100)))
649        self.assertNotEqual(range(2**200, 2**201, 2**100),
650                            range(2**200, 2**201 + 1, 2**100))
651
652        # Order comparisons are not implemented for ranges.
653        with self.assertRaises(TypeError):
654            range(0) < range(0)
655        with self.assertRaises(TypeError):
656            range(0) > range(0)
657        with self.assertRaises(TypeError):
658            range(0) <= range(0)
659        with self.assertRaises(TypeError):
660            range(0) >= range(0)
661
662
663    def test_attributes(self):
664        # test the start, stop and step attributes of range objects
665        self.assert_attrs(range(0), 0, 0, 1)
666        self.assert_attrs(range(10), 0, 10, 1)
667        self.assert_attrs(range(-10), 0, -10, 1)
668        self.assert_attrs(range(0, 10, 1), 0, 10, 1)
669        self.assert_attrs(range(0, 10, 3), 0, 10, 3)
670        self.assert_attrs(range(10, 0, -1), 10, 0, -1)
671        self.assert_attrs(range(10, 0, -3), 10, 0, -3)
672        self.assert_attrs(range(True), 0, 1, 1)
673        self.assert_attrs(range(False, True), 0, 1, 1)
674        self.assert_attrs(range(False, True, True), 0, 1, 1)
675
676    def assert_attrs(self, rangeobj, start, stop, step):
677        self.assertEqual(rangeobj.start, start)
678        self.assertEqual(rangeobj.stop, stop)
679        self.assertEqual(rangeobj.step, step)
680        self.assertIs(type(rangeobj.start), int)
681        self.assertIs(type(rangeobj.stop), int)
682        self.assertIs(type(rangeobj.step), int)
683
684        with self.assertRaises(AttributeError):
685            rangeobj.start = 0
686        with self.assertRaises(AttributeError):
687            rangeobj.stop = 10
688        with self.assertRaises(AttributeError):
689            rangeobj.step = 1
690
691        with self.assertRaises(AttributeError):
692            del rangeobj.start
693        with self.assertRaises(AttributeError):
694            del rangeobj.stop
695        with self.assertRaises(AttributeError):
696            del rangeobj.step
697
698if __name__ == "__main__":
699    unittest.main()
700