(root)/
Python-3.12.0/
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                  it.__setstate__(2**32 + 1)  # undocumented way to advance an iterator
     411                  d = pickle.dumps(it, proto)
     412                  it = pickle.loads(d)
     413                  self.assertEqual(next(it), 2**32 + 1)
     414  
     415      def test_exhausted_iterator_pickling(self):
     416          for proto in range(pickle.HIGHEST_PROTOCOL + 1):
     417              r = range(2**65, 2**65+2)
     418              i = iter(r)
     419              while True:
     420                  r = next(i)
     421                  if r == 2**65+1:
     422                      break
     423              d = pickle.dumps(i, proto)
     424              i2 = pickle.loads(d)
     425              self.assertEqual(list(i), [])
     426              self.assertEqual(list(i2), [])
     427  
     428      def test_large_exhausted_iterator_pickling(self):
     429          for proto in range(pickle.HIGHEST_PROTOCOL + 1):
     430              r = range(20)
     431              i = iter(r)
     432              while True:
     433                  r = next(i)
     434                  if r == 19:
     435                      break
     436              d = pickle.dumps(i, proto)
     437              i2 = pickle.loads(d)
     438              self.assertEqual(list(i), [])
     439              self.assertEqual(list(i2), [])
     440  
     441      def test_iterator_unpickle_compat(self):
     442          testcases = [
     443              b'c__builtin__\niter\n(c__builtin__\nxrange\n(I10\nI20\nI2\ntRtRI2\nb.',
     444              b'c__builtin__\niter\n(c__builtin__\nxrange\n(K\nK\x14K\x02tRtRK\x02b.',
     445              b'\x80\x02c__builtin__\niter\nc__builtin__\nxrange\nK\nK\x14K\x02\x87R\x85RK\x02b.',
     446              b'\x80\x03cbuiltins\niter\ncbuiltins\nrange\nK\nK\x14K\x02\x87R\x85RK\x02b.',
     447              b'\x80\x04\x951\x00\x00\x00\x00\x00\x00\x00\x8c\x08builtins\x8c\x04iter\x93\x8c\x08builtins\x8c\x05range\x93K\nK\x14K\x02\x87R\x85RK\x02b.',
     448  
     449              b'c__builtin__\niter\n(c__builtin__\nxrange\n(L-36893488147419103232L\nI20\nI2\ntRtRL18446744073709551623L\nb.',
     450              b'c__builtin__\niter\n(c__builtin__\nxrange\n(L-36893488147419103232L\nK\x14K\x02tRtRL18446744073709551623L\nb.',
     451              b'\x80\x02c__builtin__\niter\nc__builtin__\nxrange\n\x8a\t\x00\x00\x00\x00\x00\x00\x00\x00\xfeK\x14K\x02\x87R\x85R\x8a\t\x07\x00\x00\x00\x00\x00\x00\x00\x01b.',
     452              b'\x80\x03cbuiltins\niter\ncbuiltins\nrange\n\x8a\t\x00\x00\x00\x00\x00\x00\x00\x00\xfeK\x14K\x02\x87R\x85R\x8a\t\x07\x00\x00\x00\x00\x00\x00\x00\x01b.',
     453              b'\x80\x04\x95C\x00\x00\x00\x00\x00\x00\x00\x8c\x08builtins\x8c\x04iter\x93\x8c\x08builtins\x8c\x05range\x93\x8a\t\x00\x00\x00\x00\x00\x00\x00\x00\xfeK\x14K\x02\x87R\x85R\x8a\t\x07\x00\x00\x00\x00\x00\x00\x00\x01b.',
     454          ]
     455          for t in testcases:
     456              it = pickle.loads(t)
     457              self.assertEqual(list(it), [14, 16, 18])
     458  
     459      def test_iterator_setstate(self):
     460          it = iter(range(10, 20, 2))
     461          it.__setstate__(2)
     462          self.assertEqual(list(it), [14, 16, 18])
     463          it = reversed(range(10, 20, 2))
     464          it.__setstate__(3)
     465          self.assertEqual(list(it), [12, 10])
     466          it = iter(range(-2**65, 20, 2))
     467          it.__setstate__(2**64 + 7)
     468          self.assertEqual(list(it), [14, 16, 18])
     469          it = reversed(range(10, 2**65, 2))
     470          it.__setstate__(2**64 - 7)
     471          self.assertEqual(list(it), [12, 10])
     472  
     473      def test_odd_bug(self):
     474          # This used to raise a "SystemError: NULL result without error"
     475          # because the range validation step was eating the exception
     476          # before NULL was returned.
     477          with self.assertRaises(TypeError):
     478              range([], 1, -1)
     479  
     480      def test_types(self):
     481          # Non-integer objects *equal* to any of the range's items are supposed
     482          # to be contained in the range.
     483          self.assertIn(1.0, range(3))
     484          self.assertIn(True, range(3))
     485          self.assertIn(1+0j, range(3))
     486  
     487          self.assertIn(ALWAYS_EQ, range(3))
     488  
     489          # Objects are never coerced into other types for comparison.
     490          class ESC[4;38;5;81mC2:
     491              def __int__(self): return 1
     492              def __index__(self): return 1
     493          self.assertNotIn(C2(), range(3))
     494          # ..except if explicitly told so.
     495          self.assertIn(int(C2()), range(3))
     496  
     497          # Check that the range.__contains__ optimization is only
     498          # used for ints, not for instances of subclasses of int.
     499          class ESC[4;38;5;81mC3(ESC[4;38;5;149mint):
     500              def __eq__(self, other): return True
     501          self.assertIn(C3(11), range(10))
     502          self.assertIn(C3(11), list(range(10)))
     503  
     504      def test_strided_limits(self):
     505          r = range(0, 101, 2)
     506          self.assertIn(0, r)
     507          self.assertNotIn(1, r)
     508          self.assertIn(2, r)
     509          self.assertNotIn(99, r)
     510          self.assertIn(100, r)
     511          self.assertNotIn(101, r)
     512  
     513          r = range(0, -20, -1)
     514          self.assertIn(0, r)
     515          self.assertIn(-1, r)
     516          self.assertIn(-19, r)
     517          self.assertNotIn(-20, r)
     518  
     519          r = range(0, -20, -2)
     520          self.assertIn(-18, r)
     521          self.assertNotIn(-19, r)
     522          self.assertNotIn(-20, r)
     523  
     524      def test_empty(self):
     525          r = range(0)
     526          self.assertNotIn(0, r)
     527          self.assertNotIn(1, r)
     528  
     529          r = range(0, -10)
     530          self.assertNotIn(0, r)
     531          self.assertNotIn(-1, r)
     532          self.assertNotIn(1, r)
     533  
     534      def test_range_iterators(self):
     535          # exercise 'fast' iterators, that use a rangeiterobject internally.
     536          # see issue 7298
     537          limits = [base + jiggle
     538                    for M in (2**32, 2**64)
     539                    for base in (-M, -M//2, 0, M//2, M)
     540                    for jiggle in (-2, -1, 0, 1, 2)]
     541          test_ranges = [(start, end, step)
     542                         for start in limits
     543                         for end in limits
     544                         for step in (-2**63, -2**31, -2, -1, 1, 2)]
     545          test_ranges += [(-2**63, 2**63-2, 1)] # regression test for gh-100810
     546  
     547          for start, end, step in test_ranges:
     548              iter1 = range(start, end, step)
     549              iter2 = pyrange(start, end, step)
     550              test_id = "range({}, {}, {})".format(start, end, step)
     551              # check first 100 entries
     552              self.assert_iterators_equal(iter1, iter2, test_id, limit=100)
     553  
     554              iter1 = reversed(range(start, end, step))
     555              iter2 = pyrange_reversed(start, end, step)
     556              test_id = "reversed(range({}, {}, {}))".format(start, end, step)
     557              self.assert_iterators_equal(iter1, iter2, test_id, limit=100)
     558  
     559      def test_range_iterators_invocation(self):
     560          # verify range iterators instances cannot be created by
     561          # calling their type
     562          rangeiter_type = type(iter(range(0)))
     563          self.assertRaises(TypeError, rangeiter_type, 1, 3, 1)
     564          long_rangeiter_type = type(iter(range(1 << 1000)))
     565          self.assertRaises(TypeError, long_rangeiter_type, 1, 3, 1)
     566  
     567      def test_slice(self):
     568          def check(start, stop, step=None):
     569              i = slice(start, stop, step)
     570              self.assertEqual(list(r[i]), list(r)[i])
     571              self.assertEqual(len(r[i]), len(list(r)[i]))
     572          for r in [range(10),
     573                    range(0),
     574                    range(1, 9, 3),
     575                    range(8, 0, -3),
     576                    range(sys.maxsize+1, sys.maxsize+10),
     577                    ]:
     578              check(0, 2)
     579              check(0, 20)
     580              check(1, 2)
     581              check(20, 30)
     582              check(-30, -20)
     583              check(-1, 100, 2)
     584              check(0, -1)
     585              check(-1, -3, -1)
     586  
     587      def test_contains(self):
     588          r = range(10)
     589          self.assertIn(0, r)
     590          self.assertIn(1, r)
     591          self.assertIn(5.0, r)
     592          self.assertNotIn(5.1, r)
     593          self.assertNotIn(-1, r)
     594          self.assertNotIn(10, r)
     595          self.assertNotIn("", r)
     596          r = range(9, -1, -1)
     597          self.assertIn(0, r)
     598          self.assertIn(1, r)
     599          self.assertIn(5.0, r)
     600          self.assertNotIn(5.1, r)
     601          self.assertNotIn(-1, r)
     602          self.assertNotIn(10, r)
     603          self.assertNotIn("", r)
     604          r = range(0, 10, 2)
     605          self.assertIn(0, r)
     606          self.assertNotIn(1, r)
     607          self.assertNotIn(5.0, r)
     608          self.assertNotIn(5.1, r)
     609          self.assertNotIn(-1, r)
     610          self.assertNotIn(10, r)
     611          self.assertNotIn("", r)
     612          r = range(9, -1, -2)
     613          self.assertNotIn(0, r)
     614          self.assertIn(1, r)
     615          self.assertIn(5.0, r)
     616          self.assertNotIn(5.1, r)
     617          self.assertNotIn(-1, r)
     618          self.assertNotIn(10, r)
     619          self.assertNotIn("", r)
     620  
     621      def test_reverse_iteration(self):
     622          for r in [range(10),
     623                    range(0),
     624                    range(1, 9, 3),
     625                    range(8, 0, -3),
     626                    range(sys.maxsize+1, sys.maxsize+10),
     627                    ]:
     628              self.assertEqual(list(reversed(r)), list(r)[::-1])
     629  
     630      def test_issue11845(self):
     631          r = range(*slice(1, 18, 2).indices(20))
     632          values = {None, 0, 1, -1, 2, -2, 5, -5, 19, -19,
     633                    20, -20, 21, -21, 30, -30, 99, -99}
     634          for i in values:
     635              for j in values:
     636                  for k in values - {0}:
     637                      r[i:j:k]
     638  
     639      def test_comparison(self):
     640          test_ranges = [range(0), range(0, -1), range(1, 1, 3),
     641                         range(1), range(5, 6), range(5, 6, 2),
     642                         range(5, 7, 2), range(2), range(0, 4, 2),
     643                         range(0, 5, 2), range(0, 6, 2)]
     644          test_tuples = list(map(tuple, test_ranges))
     645  
     646          # Check that equality of ranges matches equality of the corresponding
     647          # tuples for each pair from the test lists above.
     648          ranges_eq = [a == b for a in test_ranges for b in test_ranges]
     649          tuples_eq = [a == b for a in test_tuples for b in test_tuples]
     650          self.assertEqual(ranges_eq, tuples_eq)
     651  
     652          # Check that != correctly gives the logical negation of ==
     653          ranges_ne = [a != b for a in test_ranges for b in test_ranges]
     654          self.assertEqual(ranges_ne, [not x for x in ranges_eq])
     655  
     656          # Equal ranges should have equal hashes.
     657          for a in test_ranges:
     658              for b in test_ranges:
     659                  if a == b:
     660                      self.assertEqual(hash(a), hash(b))
     661  
     662          # Ranges are unequal to other types (even sequence types)
     663          self.assertIs(range(0) == (), False)
     664          self.assertIs(() == range(0), False)
     665          self.assertIs(range(2) == [0, 1], False)
     666  
     667          # Huge integers aren't a problem.
     668          self.assertEqual(range(0, 2**100 - 1, 2),
     669                           range(0, 2**100, 2))
     670          self.assertEqual(hash(range(0, 2**100 - 1, 2)),
     671                           hash(range(0, 2**100, 2)))
     672          self.assertNotEqual(range(0, 2**100, 2),
     673                              range(0, 2**100 + 1, 2))
     674          self.assertEqual(range(2**200, 2**201 - 2**99, 2**100),
     675                           range(2**200, 2**201, 2**100))
     676          self.assertEqual(hash(range(2**200, 2**201 - 2**99, 2**100)),
     677                           hash(range(2**200, 2**201, 2**100)))
     678          self.assertNotEqual(range(2**200, 2**201, 2**100),
     679                              range(2**200, 2**201 + 1, 2**100))
     680  
     681          # Order comparisons are not implemented for ranges.
     682          with self.assertRaises(TypeError):
     683              range(0) < range(0)
     684          with self.assertRaises(TypeError):
     685              range(0) > range(0)
     686          with self.assertRaises(TypeError):
     687              range(0) <= range(0)
     688          with self.assertRaises(TypeError):
     689              range(0) >= range(0)
     690  
     691  
     692      def test_attributes(self):
     693          # test the start, stop and step attributes of range objects
     694          self.assert_attrs(range(0), 0, 0, 1)
     695          self.assert_attrs(range(10), 0, 10, 1)
     696          self.assert_attrs(range(-10), 0, -10, 1)
     697          self.assert_attrs(range(0, 10, 1), 0, 10, 1)
     698          self.assert_attrs(range(0, 10, 3), 0, 10, 3)
     699          self.assert_attrs(range(10, 0, -1), 10, 0, -1)
     700          self.assert_attrs(range(10, 0, -3), 10, 0, -3)
     701          self.assert_attrs(range(True), 0, 1, 1)
     702          self.assert_attrs(range(False, True), 0, 1, 1)
     703          self.assert_attrs(range(False, True, True), 0, 1, 1)
     704  
     705      def assert_attrs(self, rangeobj, start, stop, step):
     706          self.assertEqual(rangeobj.start, start)
     707          self.assertEqual(rangeobj.stop, stop)
     708          self.assertEqual(rangeobj.step, step)
     709          self.assertIs(type(rangeobj.start), int)
     710          self.assertIs(type(rangeobj.stop), int)
     711          self.assertIs(type(rangeobj.step), int)
     712  
     713          with self.assertRaises(AttributeError):
     714              rangeobj.start = 0
     715          with self.assertRaises(AttributeError):
     716              rangeobj.stop = 10
     717          with self.assertRaises(AttributeError):
     718              rangeobj.step = 1
     719  
     720          with self.assertRaises(AttributeError):
     721              del rangeobj.start
     722          with self.assertRaises(AttributeError):
     723              del rangeobj.stop
     724          with self.assertRaises(AttributeError):
     725              del rangeobj.step
     726  
     727  if __name__ == "__main__":
     728      unittest.main()