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