From 3c1df07d19000e56d6478af3d43ccd28086cd7ea Mon Sep 17 00:00:00 2001 From: Valdir Stumm Junior Date: Tue, 1 Nov 2016 00:19:38 -0200 Subject: [PATCH] add list.index() implementation --- python/common/org/python/types/List.java | 28 ++++++++- tests/datatypes/test_list.py | 72 ++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 3 deletions(-) diff --git a/python/common/org/python/types/List.java b/python/common/org/python/types/List.java index bc5ba1a90c..d47251f8a1 100644 --- a/python/common/org/python/types/List.java +++ b/python/common/org/python/types/List.java @@ -1,6 +1,7 @@ package org.python.types; import org.Python; + import java.util.Collections; import java.util.Comparator; @@ -517,19 +518,40 @@ public org.python.Object extend(org.python.Object other) { return org.python.types.NoneType.NONE; } + private int toPositiveIndex(int index) { + if (index < 0) { + return this.value.size() + index; + } + return index; + } + @org.python.Method( - __doc__ = "" + __doc__ = "L.index(value, [start, [stop]]) -> integer -- return first index of value.\nRaises ValueError if the value is not present.", + args = {"item"}, + default_args = {"start", "end"} ) public org.python.Object index(org.python.Object item, org.python.Object start, org.python.Object end) { if (start != null && !(start instanceof org.python.types.Int)) { throw new org.python.exceptions.TypeError("list indices must be integers, not " + start.typeName()); } - if (end != null && !(end instanceof org.python.types.Int)) { throw new org.python.exceptions.TypeError("list indices must be integers, not " + end.typeName()); } - throw new org.python.exceptions.NotImplementedError("list.index() has not been implemented."); + int iStart = 0, iEnd = this.value.size(); + if (end != null) { + iEnd = toPositiveIndex(((Long) end.toJava()).intValue()); + } + if (start != null) { + iStart = toPositiveIndex(((Long) start.toJava()).intValue()); + } + + for (int i = iStart; i < Math.min(iEnd, this.value.size()); i++) { + if (((org.python.types.Bool) this.value.get(i).__eq__(item)).value) { + return new org.python.types.Int(i); + } + } + throw new org.python.exceptions.ValueError(String.format("%d is not in list", ((org.python.types.Int)item).value)); } @org.python.Method( diff --git a/tests/datatypes/test_list.py b/tests/datatypes/test_list.py index 26d149d0fe..ba5f2b3bda 100644 --- a/tests/datatypes/test_list.py +++ b/tests/datatypes/test_list.py @@ -301,6 +301,78 @@ def test_copy(self): print(x[0] is y[0]) """) + def test_index(self): + self.assertCodeExecution(""" + x = [1, 2, 3] + print(x.index(1)) + """) + + self.assertCodeExecution(""" + x = [1, 2, 1] + print(x.index(1, 1)) + """) + + self.assertCodeExecution(""" + x = [1, 2, 3, 4] + print(x.index(4, 0, len(x))) + """) + + self.assertCodeExecution(""" + x = [1, 2, 3, 4] + print(x.index(2, 1, 2)) + """) + + self.assertCodeExecution(""" + x = [1, 2, 3, 4] + print(x.index(2, 0, 10)) + """) + + self.assertCodeExecution(""" + x = [1, 2, 1] + print(x.index(1, 0, -2)) + """) + + self.assertCodeExecution(""" + x = [1, 2, 1] + print(x.index(1, -3, -2)) + """) + + # cases for 'ValueError: not in list' + self.assertCodeExecution(""" + x = [1, 2, 3] + print(x.index(4)) + """) + + self.assertCodeExecution(""" + x = [1, 2, 1] + print(x.index(2, 0, 1)) + """) + + self.assertCodeExecution(""" + x = [1, 2, 3, 4] + print(x.index(4, 0, 3)) + """) + + self.assertCodeExecution(""" + x = [1, 2, 1] + print(x.index(3, 0, 10)) + """) + + self.assertCodeExecution(""" + x = [1, 2, 3, 4] + print(x.index(2, 10, 20)) + """) + + self.assertCodeExecution(""" + x = [1, 2, 3, 4] + print(x.index(2, 10, 0)) + """) + + self.assertCodeExecution(""" + x = [] + print(x.index(1, 0, 10)) + """) + class UnaryListOperationTests(UnaryOperationTestCase, TranspileTestCase): data_type = 'list'