test_index.py 9.63 KB
Newer Older
1 2 3
import unittest
from test import test_support
import operator
4
from sys import maxint
5 6
maxsize = test_support.MAX_Py_ssize_t
minsize = -maxsize-1
7 8 9 10 11 12 13 14 15

class oldstyle:
    def __index__(self):
        return self.ind

class newstyle(object):
    def __index__(self):
        return self.ind

16 17 18 19 20 21 22 23
class TrapInt(int):
    def __index__(self):
        return self

class TrapLong(long):
    def __index__(self):
        return self

24
class BaseTestCase(unittest.TestCase):
25 26 27
    def setUp(self):
        self.o = oldstyle()
        self.n = newstyle()
28

29 30 31
    def test_basic(self):
        self.o.ind = -2
        self.n.ind = 2
32 33
        self.assertEqual(operator.index(self.o), -2)
        self.assertEqual(operator.index(self.n), 2)
Tim Peters's avatar
Tim Peters committed
34

35 36 37 38 39 40 41 42 43
    def test_slice(self):
        self.o.ind = 1
        self.n.ind = 2
        slc = slice(self.o, self.o, self.o)
        check_slc = slice(1, 1, 1)
        self.assertEqual(slc.indices(self.o), check_slc.indices(1))
        slc = slice(self.n, self.n, self.n)
        check_slc = slice(2, 2, 2)
        self.assertEqual(slc.indices(self.n), check_slc.indices(2))
44

45 46 47 48 49 50 51 52
    def test_wrappers(self):
        self.o.ind = 4
        self.n.ind = 5
        self.assertEqual(6 .__index__(), 6)
        self.assertEqual(-7L.__index__(), -7)
        self.assertEqual(self.o.__index__(), 4)
        self.assertEqual(self.n.__index__(), 5)

53 54 55 56 57 58
    def test_subclasses(self):
        r = range(10)
        self.assertEqual(r[TrapInt(5):TrapInt(10)], r[5:10])
        self.assertEqual(r[TrapLong(5):TrapLong(10)], r[5:10])
        self.assertEqual(slice(TrapInt()).indices(0), (0,0,1))
        self.assertEqual(slice(TrapLong(0)).indices(0), (0,0,1))
Tim Peters's avatar
Tim Peters committed
59

60 61 62
    def test_error(self):
        self.o.ind = 'dumb'
        self.n.ind = 'bad'
63 64 65 66
        self.assertRaises(TypeError, operator.index, self.o)
        self.assertRaises(TypeError, operator.index, self.n)
        self.assertRaises(TypeError, slice(self.o).indices, 0)
        self.assertRaises(TypeError, slice(self.n).indices, 0)
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82


class SeqTestCase(unittest.TestCase):
    # This test case isn't run directly. It just defines common tests
    # to the different sequence types below
    def setUp(self):
        self.o = oldstyle()
        self.n = newstyle()
        self.o2 = oldstyle()
        self.n2 = newstyle()

    def test_index(self):
        self.o.ind = -2
        self.n.ind = 2
        self.assertEqual(self.seq[self.n], self.seq[2])
        self.assertEqual(self.seq[self.o], self.seq[-2])
83 84 85 86 87 88

    def test_slice(self):
        self.o.ind = 1
        self.o2.ind = 3
        self.n.ind = 2
        self.n2.ind = 4
89 90
        self.assertEqual(self.seq[self.o:self.o2], self.seq[1:3])
        self.assertEqual(self.seq[self.n:self.n2], self.seq[2:4])
91

92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
    def test_slice_bug7532(self):
        seqlen = len(self.seq)
        self.o.ind = int(seqlen * 1.5)
        self.n.ind = seqlen + 2
        self.assertEqual(self.seq[self.o:], self.seq[0:0])
        self.assertEqual(self.seq[:self.o], self.seq)
        self.assertEqual(self.seq[self.n:], self.seq[0:0])
        self.assertEqual(self.seq[:self.n], self.seq)
        if isinstance(self.seq, ClassicSeq):
            return
        # These tests fail for ClassicSeq (see bug #7532)
        self.o2.ind = -seqlen - 2
        self.n2.ind = -int(seqlen * 1.5)
        self.assertEqual(self.seq[self.o2:], self.seq)
        self.assertEqual(self.seq[:self.o2], self.seq[0:0])
        self.assertEqual(self.seq[self.n2:], self.seq)
        self.assertEqual(self.seq[:self.n2], self.seq[0:0])

110 111 112
    def test_repeat(self):
        self.o.ind = 3
        self.n.ind = 2
113 114 115 116
        self.assertEqual(self.seq * self.o, self.seq * 3)
        self.assertEqual(self.seq * self.n, self.seq * 2)
        self.assertEqual(self.o * self.seq, self.seq * 3)
        self.assertEqual(self.n * self.seq, self.seq * 2)
117 118

    def test_wrappers(self):
119 120 121 122 123 124 125 126 127
        self.o.ind = 4
        self.n.ind = 5
        self.assertEqual(self.seq.__getitem__(self.o), self.seq[4])
        self.assertEqual(self.seq.__mul__(self.o), self.seq * 4)
        self.assertEqual(self.seq.__rmul__(self.o), self.seq * 4)
        self.assertEqual(self.seq.__getitem__(self.n), self.seq[5])
        self.assertEqual(self.seq.__mul__(self.n), self.seq * 5)
        self.assertEqual(self.seq.__rmul__(self.n), self.seq * 5)

128 129 130
    def test_subclasses(self):
        self.assertEqual(self.seq[TrapInt()], self.seq[0])
        self.assertEqual(self.seq[TrapLong()], self.seq[0])
131 132 133 134 135

    def test_error(self):
        self.o.ind = 'dumb'
        self.n.ind = 'bad'
        indexobj = lambda x, obj: obj.seq[x]
136 137
        self.assertRaises(TypeError, indexobj, self.o, self)
        self.assertRaises(TypeError, indexobj, self.n, self)
138
        sliceobj = lambda x, obj: obj.seq[x:]
139 140
        self.assertRaises(TypeError, sliceobj, self.o, self)
        self.assertRaises(TypeError, sliceobj, self.n, self)
141 142 143


class ListTestCase(SeqTestCase):
144 145 146
    seq = [0,10,20,30,40,50]

    def test_setdelitem(self):
147 148
        self.o.ind = -2
        self.n.ind = 2
149 150 151 152 153
        lst = list('ab!cdefghi!j')
        del lst[self.o]
        del lst[self.n]
        lst[self.o] = 'X'
        lst[self.n] = 'Y'
154
        self.assertEqual(lst, list('abYdefghXj'))
155

156 157
        lst = [5, 6, 7, 8, 9, 10, 11]
        lst.__setitem__(self.n, "here")
158
        self.assertEqual(lst, [5, 6, "here", 8, 9, 10, 11])
159
        lst.__delitem__(self.n)
160
        self.assertEqual(lst, [5, 6, 8, 9, 10, 11])
161

162 163 164 165 166
    def test_inplace_repeat(self):
        self.o.ind = 2
        self.n.ind = 3
        lst = [6, 4]
        lst *= self.o
167
        self.assertEqual(lst, [6, 4, 6, 4])
168
        lst *= self.n
169
        self.assertEqual(lst, [6, 4, 6, 4] * 3)
170

171 172
        lst = [5, 6, 7, 8, 9, 11]
        l2 = lst.__imul__(self.n)
173
        self.assertIs(l2, lst)
174
        self.assertEqual(lst, [5, 6, 7, 8, 9, 11] * 3)
175 176


177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
class _BaseSeq:

    def __init__(self, iterable):
        self._list = list(iterable)

    def __repr__(self):
        return repr(self._list)

    def __eq__(self, other):
        return self._list == other

    def __len__(self):
        return len(self._list)

    def __mul__(self, n):
        return self.__class__(self._list*n)
    __rmul__ = __mul__

    def __getitem__(self, index):
        return self._list[index]


class _GetSliceMixin:

    def __getslice__(self, i, j):
        return self._list.__getslice__(i, j)


class ClassicSeq(_BaseSeq): pass
class NewSeq(_BaseSeq, object): pass
class ClassicSeqDeprecated(_GetSliceMixin, ClassicSeq): pass
class NewSeqDeprecated(_GetSliceMixin, NewSeq): pass


211
class TupleTestCase(SeqTestCase):
212
    seq = (0,10,20,30,40,50)
213

214
class StringTestCase(SeqTestCase):
215
    seq = "this is a test"
216

217 218 219
class ByteArrayTestCase(SeqTestCase):
    seq = bytearray("this is a test")

220
class UnicodeTestCase(SeqTestCase):
221
    seq = u"this is a test"
222

223 224 225 226 227 228 229 230 231 232 233 234
class ClassicSeqTestCase(SeqTestCase):
    seq = ClassicSeq((0,10,20,30,40,50))

class NewSeqTestCase(SeqTestCase):
    seq = NewSeq((0,10,20,30,40,50))

class ClassicSeqDeprecatedTestCase(SeqTestCase):
    seq = ClassicSeqDeprecated((0,10,20,30,40,50))

class NewSeqDeprecatedTestCase(SeqTestCase):
    seq = NewSeqDeprecated((0,10,20,30,40,50))

235

236
class XRangeTestCase(unittest.TestCase):
237

238 239 240
    def test_xrange(self):
        n = newstyle()
        n.ind = 5
241 242 243 244 245 246 247 248 249 250 251 252 253
        self.assertEqual(xrange(1, 20)[n], 6)
        self.assertEqual(xrange(1, 20).__getitem__(n), 6)

class OverflowTestCase(unittest.TestCase):

    def setUp(self):
        self.pos = 2**100
        self.neg = -self.pos

    def test_large_longs(self):
        self.assertEqual(self.pos.__index__(), self.pos)
        self.assertEqual(self.neg.__index__(), self.neg)

254
    def _getitem_helper(self, base):
255 256 257 258 259 260 261 262 263 264 265 266 267 268
        class GetItem(base):
            def __len__(self):
                return maxint # cannot return long here
            def __getitem__(self, key):
                return key
        x = GetItem()
        self.assertEqual(x[self.pos], self.pos)
        self.assertEqual(x[self.neg], self.neg)
        self.assertEqual(x[self.neg:self.pos].indices(maxsize),
                         (0, maxsize, 1))
        self.assertEqual(x[self.neg:self.pos:1].indices(maxsize),
                         (0, maxsize, 1))

    def _getslice_helper_deprecated(self, base):
269
        class GetItem(base):
270
            def __len__(self):
271
                return maxint # cannot return long here
272 273 274 275 276 277 278
            def __getitem__(self, key):
                return key
            def __getslice__(self, i, j):
                return i, j
        x = GetItem()
        self.assertEqual(x[self.pos], self.pos)
        self.assertEqual(x[self.neg], self.neg)
279
        self.assertEqual(x[self.neg:self.pos], (maxint+minsize, maxsize))
280 281
        self.assertEqual(x[self.neg:self.pos:1].indices(maxsize),
                         (0, maxsize, 1))
282

283 284
    def test_getitem(self):
        self._getitem_helper(object)
285
        with test_support.check_py3k_warnings():
286
            self._getslice_helper_deprecated(object)
287 288 289

    def test_getitem_classic(self):
        class Empty: pass
290 291
        # XXX This test fails (see bug #7532)
        #self._getitem_helper(Empty)
292
        with test_support.check_py3k_warnings():
293
            self._getslice_helper_deprecated(Empty)
294

295
    def test_sequence_repeat(self):
296 297
        self.assertRaises(OverflowError, lambda: "a" * self.pos)
        self.assertRaises(OverflowError, lambda: "a" * self.neg)
298 299 300 301


def test_main():
    test_support.run_unittest(
302
        BaseTestCase,
303 304
        ListTestCase,
        TupleTestCase,
305
        ByteArrayTestCase,
306
        StringTestCase,
307
        UnicodeTestCase,
308 309
        ClassicSeqTestCase,
        NewSeqTestCase,
310
        XRangeTestCase,
311
        OverflowTestCase,
312
    )
313
    with test_support.check_py3k_warnings():
314 315 316 317 318
        test_support.run_unittest(
            ClassicSeqDeprecatedTestCase,
            NewSeqDeprecatedTestCase,
        )

319 320 321

if __name__ == "__main__":
    test_main()