test_index.py 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. import unittest
  2. from test import support
  3. import operator
  4. maxsize = support.MAX_Py_ssize_t
  5. class newstyle:
  6. def __index__(self):
  7. return self.ind
  8. class TrapInt(int):
  9. def __index__(self):
  10. return int(self)
  11. class BaseTestCase(unittest.TestCase):
  12. def setUp(self):
  13. self.o = newstyle()
  14. self.n = newstyle()
  15. def test_basic(self):
  16. self.o.ind = -2
  17. self.n.ind = 2
  18. self.assertEqual(operator.index(self.o), -2)
  19. self.assertEqual(operator.index(self.n), 2)
  20. def test_slice(self):
  21. self.o.ind = 1
  22. self.n.ind = 2
  23. slc = slice(self.o, self.o, self.o)
  24. check_slc = slice(1, 1, 1)
  25. self.assertEqual(slc.indices(self.o), check_slc.indices(1))
  26. slc = slice(self.n, self.n, self.n)
  27. check_slc = slice(2, 2, 2)
  28. self.assertEqual(slc.indices(self.n), check_slc.indices(2))
  29. def test_wrappers(self):
  30. self.o.ind = 4
  31. self.n.ind = 5
  32. self.assertEqual(6 .__index__(), 6)
  33. self.assertEqual(-7 .__index__(), -7)
  34. self.assertEqual(self.o.__index__(), 4)
  35. self.assertEqual(self.n.__index__(), 5)
  36. self.assertEqual(True.__index__(), 1)
  37. self.assertEqual(False.__index__(), 0)
  38. def test_subclasses(self):
  39. r = list(range(10))
  40. self.assertEqual(r[TrapInt(5):TrapInt(10)], r[5:10])
  41. self.assertEqual(slice(TrapInt()).indices(0), (0,0,1))
  42. def test_error(self):
  43. self.o.ind = 'dumb'
  44. self.n.ind = 'bad'
  45. self.assertRaises(TypeError, operator.index, self.o)
  46. self.assertRaises(TypeError, operator.index, self.n)
  47. self.assertRaises(TypeError, slice(self.o).indices, 0)
  48. self.assertRaises(TypeError, slice(self.n).indices, 0)
  49. def test_int_subclass_with_index(self):
  50. # __index__ should be used when computing indices, even for int
  51. # subclasses. See issue #17576.
  52. class MyInt(int):
  53. def __index__(self):
  54. return int(str(self)) + 1
  55. my_int = MyInt(7)
  56. direct_index = my_int.__index__()
  57. operator_index = operator.index(my_int)
  58. self.assertEqual(direct_index, 8)
  59. self.assertEqual(operator_index, 7)
  60. # Both results should be of exact type int.
  61. self.assertIs(type(direct_index), int)
  62. #self.assertIs(type(operator_index), int)
  63. def test_index_returns_int_subclass(self):
  64. class BadInt:
  65. def __index__(self):
  66. return True
  67. class BadInt2(int):
  68. def __index__(self):
  69. return True
  70. bad_int = BadInt()
  71. with self.assertWarns(DeprecationWarning):
  72. n = operator.index(bad_int)
  73. self.assertEqual(n, 1)
  74. bad_int = BadInt2()
  75. n = operator.index(bad_int)
  76. self.assertEqual(n, 0)
  77. class SeqTestCase:
  78. # This test case isn't run directly. It just defines common tests
  79. # to the different sequence types below
  80. def setUp(self):
  81. self.o = newstyle()
  82. self.n = newstyle()
  83. self.o2 = newstyle()
  84. self.n2 = newstyle()
  85. def test_index(self):
  86. self.o.ind = -2
  87. self.n.ind = 2
  88. self.assertEqual(self.seq[self.n], self.seq[2])
  89. self.assertEqual(self.seq[self.o], self.seq[-2])
  90. def test_slice(self):
  91. self.o.ind = 1
  92. self.o2.ind = 3
  93. self.n.ind = 2
  94. self.n2.ind = 4
  95. self.assertEqual(self.seq[self.o:self.o2], self.seq[1:3])
  96. self.assertEqual(self.seq[self.n:self.n2], self.seq[2:4])
  97. def test_slice_bug7532(self):
  98. seqlen = len(self.seq)
  99. self.o.ind = int(seqlen * 1.5)
  100. self.n.ind = seqlen + 2
  101. self.assertEqual(self.seq[self.o:], self.seq[0:0])
  102. self.assertEqual(self.seq[:self.o], self.seq)
  103. self.assertEqual(self.seq[self.n:], self.seq[0:0])
  104. self.assertEqual(self.seq[:self.n], self.seq)
  105. self.o2.ind = -seqlen - 2
  106. self.n2.ind = -int(seqlen * 1.5)
  107. self.assertEqual(self.seq[self.o2:], self.seq)
  108. self.assertEqual(self.seq[:self.o2], self.seq[0:0])
  109. self.assertEqual(self.seq[self.n2:], self.seq)
  110. self.assertEqual(self.seq[:self.n2], self.seq[0:0])
  111. def test_repeat(self):
  112. self.o.ind = 3
  113. self.n.ind = 2
  114. self.assertEqual(self.seq * self.o, self.seq * 3)
  115. self.assertEqual(self.seq * self.n, self.seq * 2)
  116. self.assertEqual(self.o * self.seq, self.seq * 3)
  117. self.assertEqual(self.n * self.seq, self.seq * 2)
  118. def test_wrappers(self):
  119. self.o.ind = 4
  120. self.n.ind = 5
  121. self.assertEqual(self.seq.__getitem__(self.o), self.seq[4])
  122. self.assertEqual(self.seq.__mul__(self.o), self.seq * 4)
  123. self.assertEqual(self.seq.__rmul__(self.o), self.seq * 4)
  124. self.assertEqual(self.seq.__getitem__(self.n), self.seq[5])
  125. self.assertEqual(self.seq.__mul__(self.n), self.seq * 5)
  126. self.assertEqual(self.seq.__rmul__(self.n), self.seq * 5)
  127. def test_subclasses(self):
  128. self.assertEqual(self.seq[TrapInt()], self.seq[0])
  129. def test_error(self):
  130. self.o.ind = 'dumb'
  131. self.n.ind = 'bad'
  132. indexobj = lambda x, obj: obj.seq[x]
  133. self.assertRaises(TypeError, indexobj, self.o, self)
  134. self.assertRaises(TypeError, indexobj, self.n, self)
  135. sliceobj = lambda x, obj: obj.seq[x:]
  136. self.assertRaises(TypeError, sliceobj, self.o, self)
  137. self.assertRaises(TypeError, sliceobj, self.n, self)
  138. class ListTestCase(SeqTestCase, unittest.TestCase):
  139. seq = [0,10,20,30,40,50]
  140. def test_setdelitem(self):
  141. self.o.ind = -2
  142. self.n.ind = 2
  143. lst = list('ab!cdefghi!j')
  144. del lst[self.o]
  145. del lst[self.n]
  146. lst[self.o] = 'X'
  147. lst[self.n] = 'Y'
  148. self.assertEqual(lst, list('abYdefghXj'))
  149. lst = [5, 6, 7, 8, 9, 10, 11]
  150. lst.__setitem__(self.n, "here")
  151. self.assertEqual(lst, [5, 6, "here", 8, 9, 10, 11])
  152. lst.__delitem__(self.n)
  153. self.assertEqual(lst, [5, 6, 8, 9, 10, 11])
  154. def test_inplace_repeat(self):
  155. self.o.ind = 2
  156. self.n.ind = 3
  157. lst = [6, 4]
  158. lst *= self.o
  159. self.assertEqual(lst, [6, 4, 6, 4])
  160. lst *= self.n
  161. self.assertEqual(lst, [6, 4, 6, 4] * 3)
  162. lst = [5, 6, 7, 8, 9, 11]
  163. l2 = lst.__imul__(self.n)
  164. self.assertIs(l2, lst)
  165. self.assertEqual(lst, [5, 6, 7, 8, 9, 11] * 3)
  166. class NewSeq:
  167. def __init__(self, iterable):
  168. self._list = list(iterable)
  169. def __repr__(self):
  170. return repr(self._list)
  171. def __eq__(self, other):
  172. return self._list == other
  173. def __len__(self):
  174. return len(self._list)
  175. def __mul__(self, n):
  176. return self.__class__(self._list*n)
  177. __rmul__ = __mul__
  178. def __getitem__(self, index):
  179. return self._list[index]
  180. class TupleTestCase(SeqTestCase, unittest.TestCase):
  181. seq = (0,10,20,30,40,50)
  182. class ByteArrayTestCase(SeqTestCase, unittest.TestCase):
  183. seq = bytearray(b"this is a test")
  184. class BytesTestCase(SeqTestCase, unittest.TestCase):
  185. seq = b"this is a test"
  186. class StringTestCase(SeqTestCase, unittest.TestCase):
  187. seq = "this is a test"
  188. class NewSeqTestCase(SeqTestCase, unittest.TestCase):
  189. seq = NewSeq((0,10,20,30,40,50))
  190. class RangeTestCase(unittest.TestCase):
  191. def test_range(self):
  192. n = newstyle()
  193. n.ind = 5
  194. self.assertEqual(range(1, 20)[n], 6)
  195. self.assertEqual(range(1, 20).__getitem__(n), 6)
  196. class OverflowTestCase(unittest.TestCase):
  197. def setUp(self):
  198. self.pos = 2**100
  199. self.neg = -self.pos
  200. def test_large_longs(self):
  201. self.assertEqual(self.pos.__index__(), self.pos)
  202. self.assertEqual(self.neg.__index__(), self.neg)
  203. def test_getitem(self):
  204. class GetItem:
  205. def __len__(self):
  206. assert False, "__len__ should not be invoked"
  207. def __getitem__(self, key):
  208. return key
  209. x = GetItem()
  210. self.assertEqual(x[self.pos], self.pos)
  211. self.assertEqual(x[self.neg], self.neg)
  212. self.assertEqual(x[self.neg:self.pos].indices(maxsize),
  213. (0, maxsize, 1))
  214. self.assertEqual(x[self.neg:self.pos:1].indices(maxsize),
  215. (0, maxsize, 1))
  216. def test_sequence_repeat(self):
  217. self.assertRaises(OverflowError, lambda: "a" * self.pos)
  218. self.assertRaises(OverflowError, lambda: "a" * self.neg)
  219. if __name__ == "__main__":
  220. unittest.main()