diff -r 2c30e000fbb4 -r f59ed230971a Lib/test/test_enumerate.py --- a/Lib/test/test_enumerate.py Tue May 13 16:32:13 2014 +0000 +++ b/Lib/test/test_enumerate.py Wed May 14 21:07:13 2014 -0700 @@ -100,7 +100,8 @@ 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', 2) # too many arguments + self.assertRaises(TypeError, self.enum, 'abc', 'a') # wrong type + self.assertRaises(TypeError, self.enum, 'abc', 2, 3) # too many arguments def test_tuple_reuse(self): # Tests an implementation detail where tuple is reused diff -r 2c30e000fbb4 -r f59ed230971a Lib/test/test_enumerate_jy.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Lib/test/test_enumerate_jy.py Wed May 14 21:07:13 2014 -0700 @@ -0,0 +1,47 @@ +import unittest +import sys + +from test import test_support + + +class EnumerateJyTestCase(unittest.TestCase): + + enum = enumerate + seq, start, res = 'abc', 5, [(5, 'a'), (6, 'b'), (7, 'c')] + + def test_start_kwarg_1(self): + e = self.enum(self.seq, start=self.start) + self.assertEqual(iter(e), e) + self.assertEqual(list(e), self.res) + + def test_start_kwarg_2(self): + e = self.enum(start=self.start, sequence=self.seq) + self.assertEqual(iter(e), e) + self.assertEqual(list(e), self.res) + + def test_start_pos(self): + e = self.enum(self.seq, self.start) + self.assertEqual(iter(e), e) + self.assertEqual(list(e), self.res) + + def test_start_maxint(self): + e = self.enum(self.seq, sys.maxint) + self.assertEqual(list(e), [(2147483647, 'a'), (2147483648L, 'b'), (2147483649L, 'c')]) + + +def test_main(verbose=None): + testclasses = (EnumerateJyTestCase,) + test_support.run_unittest(*testclasses) + + # verify reference counting + import sys + if verbose and hasattr(sys, "gettotalrefcount"): + counts = [None] * 5 + for i in xrange(len(counts)): + test_support.run_unittest(*testclasses) + counts[i] = sys.gettotalrefcount() + print counts + +if __name__ == "__main__": + test_main(verbose=True) + diff -r 2c30e000fbb4 -r f59ed230971a src/org/python/core/PyEnumerate.java --- a/src/org/python/core/PyEnumerate.java Tue May 13 16:32:13 2014 +0000 +++ b/src/org/python/core/PyEnumerate.java Wed May 14 21:07:13 2014 -0700 @@ -5,6 +5,8 @@ import org.python.expose.ExposedNew; import org.python.expose.ExposedType; +import java.math.BigInteger; + /** * The Python builtin enumerate type. */ @@ -15,6 +17,7 @@ /** Current index of enumeration. */ private long index; + private PyLong longindex; // index for sequences >= Integer.MAX_VALUE /** Secondary iterator of enumeration. */ private PyObject sit; @@ -23,14 +26,19 @@ super(subType); } - public PyEnumerate(PyType subType, PyObject seq) { + public PyEnumerate(PyType subType, PyObject seq, PyLong start) { super(subType); - index = 0; + if (start.getValue().compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) > 0) { + index = -1; + longindex = start; + } else { + index = start.asLong(); + } sit = seq.__iter__(); } - public PyEnumerate(PyObject seq) { - this(TYPE, seq); + public PyEnumerate(PyObject seq, PyLong start) { + this(TYPE, seq, start); } public PyObject next() { @@ -50,14 +58,31 @@ @ExposedNew public final static PyObject enumerate_new(PyNewWrapper new_, boolean init, PyType subtype, PyObject[] args, String[] keywords) { - if (args.length != 1) { - throw PyBuiltinCallable.DefaultInfo.unexpectedCall(args.length, false, "enumerate", 0, - 1); + if (args.length > 2 || args.length <= 0) { + throw PyBuiltinCallable.DefaultInfo.unexpectedCall(args.length, true, "enumerate", 1, 2); } + + ArgParser ap = new ArgParser("enumerate", args, keywords, new String[] {"sequence", "start"}); + PyObject seq = ap.getPyObject(0); + PyObject startobj = ap.getPyObject(1, null); + + PyLong start; + if (startobj != null) { + if (startobj instanceof PyInteger) { + start = new PyLong(startobj.asInt()); + } else if (startobj instanceof PyLong) { + start = (PyLong) startobj; + } else { + throw Py.TypeError("'" + startobj.getType().fastGetName() + "' object cannot be interpreted as an index"); + } + } else { + start = new PyLong(0); + } + if (new_.for_type == subtype) { - return new PyEnumerate(args[0]); + return new PyEnumerate(seq, start); } else { - return new PyEnumerateDerived(subtype, args[0]); + return new PyEnumerateDerived(subtype, seq, start); } } @@ -76,6 +101,21 @@ return null; } - return new PyTuple(new PyInteger((int)index++), nextItem); + PyObject next; + if (index >= 0 && index < Integer.MAX_VALUE) { + next = new PyTuple(new PyInteger((int)index++), nextItem); + } else { + if (index == Integer.MAX_VALUE) { + next = new PyTuple(new PyInteger((int)index), nextItem); + longindex = new PyLong(index + 1); + index = -1; + } else { + assert longindex != null; + next = new PyTuple(longindex, nextItem); + longindex = (PyLong) longindex.__add__(new PyLong(1)); + } + } + + return next; } } diff -r 2c30e000fbb4 -r f59ed230971a src/org/python/core/PyEnumerateDerived.java --- a/src/org/python/core/PyEnumerateDerived.java Tue May 13 16:32:13 2014 +0000 +++ b/src/org/python/core/PyEnumerateDerived.java Wed May 14 21:07:13 2014 -0700 @@ -38,8 +38,8 @@ dict=new PyStringMap(); } - public PyEnumerateDerived(PyType subtype,PyObject seq) { - super(subtype,seq); + public PyEnumerateDerived(PyType subtype,PyObject seq,PyLong start) { + super(subtype,seq,start); slots=new PyObject[subtype.getNumSlots()]; dict=subtype.instDict(); }