diff options
author | Neal Norwitz <nnorwitz@gmail.com> | 2006-08-12 17:03:09 +0000 |
---|---|---|
committer | Neal Norwitz <nnorwitz@gmail.com> | 2006-08-12 17:03:09 +0000 |
commit | 8a87f5d37e6aab91ddc4c6491877b6cbd48a12cf (patch) | |
tree | 330bb4b553958f129b31e31ccea2a2c835b19de0 /Lib/test/test_index.py | |
parent | f3e304297e94b9b1956a4ed95debd1b163958d71 (diff) | |
download | cpython-git-8a87f5d37e6aab91ddc4c6491877b6cbd48a12cf.tar.gz |
Patch #1538606, Patch to fix __index__() clipping.
I modified this patch some by fixing style, some error checking, and adding
XXX comments. This patch requires review and some changes are to be expected.
I'm checking in now to get the greatest possible review and establish a
baseline for moving forward. I don't want this to hold up release if possible.
Diffstat (limited to 'Lib/test/test_index.py')
-rw-r--r-- | Lib/test/test_index.py | 174 |
1 files changed, 126 insertions, 48 deletions
diff --git a/Lib/test/test_index.py b/Lib/test/test_index.py index 45b3b2b6cd..b224a5017b 100644 --- a/Lib/test/test_index.py +++ b/Lib/test/test_index.py @@ -1,6 +1,7 @@ import unittest from test import test_support import operator +from sys import maxint class oldstyle: def __index__(self): @@ -10,68 +11,115 @@ class newstyle(object): def __index__(self): return self.ind +class TrapInt(int): + def __index__(self): + return self + +class TrapLong(long): + def __index__(self): + return self + class BaseTestCase(unittest.TestCase): def setUp(self): self.o = oldstyle() self.n = newstyle() - self.o2 = oldstyle() - self.n2 = newstyle() def test_basic(self): self.o.ind = -2 self.n.ind = 2 - assert(self.seq[self.n] == self.seq[2]) - assert(self.seq[self.o] == self.seq[-2]) - assert(operator.index(self.o) == -2) - assert(operator.index(self.n) == 2) + self.assertEqual(operator.index(self.o), -2) + self.assertEqual(operator.index(self.n), 2) + + 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)) + 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) + + def test_infinite_recursion(self): + self.failUnlessRaises(TypeError, operator.index, TrapInt()) + self.failUnlessRaises(TypeError, operator.index, TrapLong()) + self.failUnless(slice(TrapInt()).indices(0)==(0,0,1)) + self.failUnlessRaises(TypeError, slice(TrapLong()).indices, 0) + def test_error(self): self.o.ind = 'dumb' self.n.ind = 'bad' - myfunc = lambda x, obj: obj.seq[x] self.failUnlessRaises(TypeError, operator.index, self.o) self.failUnlessRaises(TypeError, operator.index, self.n) - self.failUnlessRaises(TypeError, myfunc, self.o, self) - self.failUnlessRaises(TypeError, myfunc, self.n, self) + self.failUnlessRaises(TypeError, slice(self.o).indices, 0) + self.failUnlessRaises(TypeError, slice(self.n).indices, 0) + + +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]) def test_slice(self): self.o.ind = 1 self.o2.ind = 3 self.n.ind = 2 self.n2.ind = 4 - assert(self.seq[self.o:self.o2] == self.seq[1:3]) - assert(self.seq[self.n:self.n2] == self.seq[2:4]) + self.assertEqual(self.seq[self.o:self.o2], self.seq[1:3]) + self.assertEqual(self.seq[self.n:self.n2], self.seq[2:4]) def test_repeat(self): self.o.ind = 3 self.n.ind = 2 - assert(self.seq * self.o == self.seq * 3) - assert(self.seq * self.n == self.seq * 2) - assert(self.o * self.seq == self.seq * 3) - assert(self.n * self.seq == self.seq * 2) + 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) def test_wrappers(self): - n = self.n - n.ind = 5 - assert n.__index__() == 5 - assert 6 .__index__() == 6 - assert -7L.__index__() == -7 - assert self.seq.__getitem__(n) == self.seq[5] - assert self.seq.__mul__(n) == self.seq * 5 - assert self.seq.__rmul__(n) == self.seq * 5 - - def test_infinite_recusion(self): - class Trap1(int): - def __index__(self): - return self - class Trap2(long): - def __index__(self): - return self - self.failUnlessRaises(TypeError, operator.getitem, self.seq, Trap1()) - self.failUnlessRaises(TypeError, operator.getitem, self.seq, Trap2()) - - -class ListTestCase(BaseTestCase): + 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) + + def test_infinite_recursion(self): + self.failUnlessRaises(TypeError, operator.getitem, self.seq, TrapInt()) + self.failUnlessRaises(TypeError, operator.getitem, self.seq, TrapLong()) + + def test_error(self): + self.o.ind = 'dumb' + self.n.ind = 'bad' + indexobj = lambda x, obj: obj.seq[x] + self.failUnlessRaises(TypeError, indexobj, self.o, self) + self.failUnlessRaises(TypeError, indexobj, self.n, self) + sliceobj = lambda x, obj: obj.seq[x:] + self.failUnlessRaises(TypeError, sliceobj, self.o, self) + self.failUnlessRaises(TypeError, sliceobj, self.n, self) + + +class ListTestCase(SeqTestCase): seq = [0,10,20,30,40,50] def test_setdelitem(self): @@ -82,36 +130,36 @@ class ListTestCase(BaseTestCase): del lst[self.n] lst[self.o] = 'X' lst[self.n] = 'Y' - assert lst == list('abYdefghXj') + self.assertEqual(lst, list('abYdefghXj')) lst = [5, 6, 7, 8, 9, 10, 11] lst.__setitem__(self.n, "here") - assert lst == [5, 6, "here", 8, 9, 10, 11] + self.assertEqual(lst, [5, 6, "here", 8, 9, 10, 11]) lst.__delitem__(self.n) - assert lst == [5, 6, 8, 9, 10, 11] + self.assertEqual(lst, [5, 6, 8, 9, 10, 11]) def test_inplace_repeat(self): self.o.ind = 2 self.n.ind = 3 lst = [6, 4] lst *= self.o - assert lst == [6, 4, 6, 4] + self.assertEqual(lst, [6, 4, 6, 4]) lst *= self.n - assert lst == [6, 4, 6, 4] * 3 + self.assertEqual(lst, [6, 4, 6, 4] * 3) lst = [5, 6, 7, 8, 9, 11] l2 = lst.__imul__(self.n) - assert l2 is lst - assert lst == [5, 6, 7, 8, 9, 11] * 3 + self.assert_(l2 is lst) + self.assertEqual(lst, [5, 6, 7, 8, 9, 11] * 3) -class TupleTestCase(BaseTestCase): +class TupleTestCase(SeqTestCase): seq = (0,10,20,30,40,50) -class StringTestCase(BaseTestCase): +class StringTestCase(SeqTestCase): seq = "this is a test" -class UnicodeTestCase(BaseTestCase): +class UnicodeTestCase(SeqTestCase): seq = u"this is a test" @@ -120,17 +168,47 @@ class XRangeTestCase(unittest.TestCase): def test_xrange(self): n = newstyle() n.ind = 5 - assert xrange(1, 20)[n] == 6 - assert xrange(1, 20).__getitem__(n) == 6 + 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) + + def test_getitem(self): + class GetItem(object): + def __len__(self): + return maxint + 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) + self.assertEqual(x[self.neg:self.pos], (-1, maxint)) + self.assertEqual(x[self.neg:self.pos:1].indices(maxint), (0, maxint, 1)) + + def test_sequence_repeat(self): + self.failUnlessRaises(OverflowError, lambda: "a" * self.pos) + self.failUnlessRaises(OverflowError, lambda: "a" * self.neg) def test_main(): test_support.run_unittest( + BaseTestCase, ListTestCase, TupleTestCase, StringTestCase, UnicodeTestCase, XRangeTestCase, + OverflowTestCase, ) if __name__ == "__main__": |