summaryrefslogtreecommitdiff
path: root/lib/python2.7/test/test_enumerate.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/python2.7/test/test_enumerate.py')
-rw-r--r--lib/python2.7/test/test_enumerate.py255
1 files changed, 255 insertions, 0 deletions
diff --git a/lib/python2.7/test/test_enumerate.py b/lib/python2.7/test/test_enumerate.py
new file mode 100644
index 0000000..6b9ff79
--- /dev/null
+++ b/lib/python2.7/test/test_enumerate.py
@@ -0,0 +1,255 @@
+import unittest
+import sys
+
+from test import test_support
+
+class G:
+ 'Sequence using __getitem__'
+ def __init__(self, seqn):
+ self.seqn = seqn
+ def __getitem__(self, i):
+ return self.seqn[i]
+
+class I:
+ 'Sequence using iterator protocol'
+ def __init__(self, seqn):
+ self.seqn = seqn
+ self.i = 0
+ def __iter__(self):
+ return self
+ def next(self):
+ if self.i >= len(self.seqn): raise StopIteration
+ v = self.seqn[self.i]
+ self.i += 1
+ return v
+
+class Ig:
+ 'Sequence using iterator protocol defined with a generator'
+ def __init__(self, seqn):
+ self.seqn = seqn
+ self.i = 0
+ def __iter__(self):
+ for val in self.seqn:
+ yield val
+
+class X:
+ 'Missing __getitem__ and __iter__'
+ def __init__(self, seqn):
+ self.seqn = seqn
+ self.i = 0
+ def next(self):
+ if self.i >= len(self.seqn): raise StopIteration
+ v = self.seqn[self.i]
+ self.i += 1
+ return v
+
+class E:
+ 'Test propagation of exceptions'
+ def __init__(self, seqn):
+ self.seqn = seqn
+ self.i = 0
+ def __iter__(self):
+ return self
+ def next(self):
+ 3 // 0
+
+class N:
+ 'Iterator missing next()'
+ def __init__(self, seqn):
+ self.seqn = seqn
+ self.i = 0
+ def __iter__(self):
+ return self
+
+class EnumerateTestCase(unittest.TestCase):
+
+ enum = enumerate
+ seq, res = 'abc', [(0,'a'), (1,'b'), (2,'c')]
+
+ def test_basicfunction(self):
+ self.assertEqual(type(self.enum(self.seq)), self.enum)
+ e = self.enum(self.seq)
+ self.assertEqual(iter(e), e)
+ self.assertEqual(list(self.enum(self.seq)), self.res)
+ self.enum.__doc__
+
+ def test_getitemseqn(self):
+ self.assertEqual(list(self.enum(G(self.seq))), self.res)
+ e = self.enum(G(''))
+ self.assertRaises(StopIteration, e.next)
+
+ def test_iteratorseqn(self):
+ self.assertEqual(list(self.enum(I(self.seq))), self.res)
+ e = self.enum(I(''))
+ self.assertRaises(StopIteration, e.next)
+
+ def test_iteratorgenerator(self):
+ self.assertEqual(list(self.enum(Ig(self.seq))), self.res)
+ e = self.enum(Ig(''))
+ self.assertRaises(StopIteration, e.next)
+
+ def test_noniterable(self):
+ self.assertRaises(TypeError, self.enum, X(self.seq))
+
+ def test_illformediterable(self):
+ self.assertRaises(TypeError, list, self.enum(N(self.seq)))
+
+ def test_exception_propagation(self):
+ self.assertRaises(ZeroDivisionError, list, self.enum(E(self.seq)))
+
+ def test_argumentcheck(self):
+ self.assertRaises(TypeError, self.enum) # no arguments
+ self.assertRaises(TypeError, self.enum, 1) # wrong type (not iterable)
+ self.assertRaises(TypeError, self.enum, 'abc', 'a') # wrong type
+ self.assertRaises(TypeError, self.enum, 'abc', 2, 3) # too many arguments
+
+ @test_support.cpython_only
+ def test_tuple_reuse(self):
+ # Tests an implementation detail where tuple is reused
+ # whenever nothing else holds a reference to it
+ self.assertEqual(len(set(map(id, list(enumerate(self.seq))))), len(self.seq))
+ self.assertEqual(len(set(map(id, enumerate(self.seq)))), min(1,len(self.seq)))
+
+class MyEnum(enumerate):
+ pass
+
+class SubclassTestCase(EnumerateTestCase):
+
+ enum = MyEnum
+
+class TestEmpty(EnumerateTestCase):
+
+ seq, res = '', []
+
+class TestBig(EnumerateTestCase):
+
+ seq = range(10,20000,2)
+ res = zip(range(20000), seq)
+
+class TestReversed(unittest.TestCase):
+
+ def test_simple(self):
+ class A:
+ def __getitem__(self, i):
+ if i < 5:
+ return str(i)
+ raise StopIteration
+ def __len__(self):
+ return 5
+ for data in 'abc', range(5), tuple(enumerate('abc')), A(), xrange(1,17,5):
+ self.assertEqual(list(data)[::-1], list(reversed(data)))
+ self.assertRaises(TypeError, reversed, {})
+ # don't allow keyword arguments
+ self.assertRaises(TypeError, reversed, [], a=1)
+
+ def test_classic_class(self):
+ class A:
+ def __reversed__(self):
+ return [2, 1]
+ self.assertEqual(list(reversed(A())), [2, 1])
+
+ def test_xrange_optimization(self):
+ x = xrange(1)
+ self.assertEqual(type(reversed(x)), type(iter(x)))
+
+ @test_support.cpython_only
+ def test_len(self):
+ # This is an implementation detail, not an interface requirement
+ from test.test_iterlen import len
+ for s in ('hello', tuple('hello'), list('hello'), xrange(5)):
+ self.assertEqual(len(reversed(s)), len(s))
+ r = reversed(s)
+ list(r)
+ self.assertEqual(len(r), 0)
+ class SeqWithWeirdLen:
+ called = False
+ def __len__(self):
+ if not self.called:
+ self.called = True
+ return 10
+ raise ZeroDivisionError
+ def __getitem__(self, index):
+ return index
+ r = reversed(SeqWithWeirdLen())
+ self.assertRaises(ZeroDivisionError, len, r)
+
+
+ def test_gc(self):
+ class Seq:
+ def __len__(self):
+ return 10
+ def __getitem__(self, index):
+ return index
+ s = Seq()
+ r = reversed(s)
+ s.r = r
+
+ def test_args(self):
+ self.assertRaises(TypeError, reversed)
+ self.assertRaises(TypeError, reversed, [], 'extra')
+
+ def test_bug1229429(self):
+ # this bug was never in reversed, it was in
+ # PyObject_CallMethod, and reversed_new calls that sometimes.
+ if not hasattr(sys, "getrefcount"):
+ return
+ def f():
+ pass
+ r = f.__reversed__ = object()
+ rc = sys.getrefcount(r)
+ for i in range(10):
+ try:
+ reversed(f)
+ except TypeError:
+ pass
+ else:
+ self.fail("non-callable __reversed__ didn't raise!")
+ self.assertEqual(rc, sys.getrefcount(r))
+
+ def test_objmethods(self):
+ # Objects must have __len__() and __getitem__() implemented.
+ class NoLen(object):
+ def __getitem__(self): return 1
+ nl = NoLen()
+ self.assertRaises(TypeError, reversed, nl)
+
+ class NoGetItem(object):
+ def __len__(self): return 2
+ ngi = NoGetItem()
+ self.assertRaises(TypeError, reversed, ngi)
+
+
+class EnumerateStartTestCase(EnumerateTestCase):
+
+ def test_basicfunction(self):
+ e = self.enum(self.seq)
+ self.assertEqual(iter(e), e)
+ self.assertEqual(list(self.enum(self.seq)), self.res)
+
+
+class TestStart(EnumerateStartTestCase):
+
+ enum = lambda self, i: enumerate(i, start=11)
+ seq, res = 'abc', [(11, 'a'), (12, 'b'), (13, 'c')]
+
+
+class TestLongStart(EnumerateStartTestCase):
+
+ enum = lambda self, i: enumerate(i, start=sys.maxint+1)
+ seq, res = 'abc', [(sys.maxint+1,'a'), (sys.maxint+2,'b'),
+ (sys.maxint+3,'c')]
+
+
+def test_main(verbose=None):
+ test_support.run_unittest(__name__)
+
+ # verify reference counting
+ if verbose and hasattr(sys, "gettotalrefcount"):
+ counts = [None] * 5
+ for i in xrange(len(counts)):
+ test_support.run_unittest(__name__)
+ counts[i] = sys.gettotalrefcount()
+ print counts
+
+if __name__ == "__main__":
+ test_main(verbose=True)