(root)/
Python-3.11.7/
Lib/
test/
test_range.py
       1  # Python test set -- built-in functions
       2  
       3  import unittest
       4  import sys
       5  import pickle
       6  import itertools
       7  from test.support import ALWAYS_EQ
       8  
       9  # pure Python implementations (3 args only), for comparison
      10  def 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  
      19  def pyrange_reversed(start, stop, step):
      20      stop += (start - stop) % step
      21      return pyrange(stop - step, start - step, -step)
      22  
      23  
      24  class ESC[4;38;5;81mRangeTest(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
      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 ESC[4;38;5;81mBadExc(ESC[4;38;5;149mException):
     284              pass
     285  
     286          class ESC[4;38;5;81mBadCmp:
     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 ESC[4;38;5;81mI:
     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 ESC[4;38;5;81mIX:
     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 ESC[4;38;5;81mIN:
     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 ESC[4;38;5;81mC2:
     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 ESC[4;38;5;81mC3(ESC[4;38;5;149mint):
     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  
     698  if __name__ == "__main__":
     699      unittest.main()