From: <zy...@us...> - 2009-04-19 00:01:14
|
Revision: 6244 http://jython.svn.sourceforge.net/jython/?rev=6244&view=rev Author: zyasoft Date: 2009-04-19 00:01:11 +0000 (Sun, 19 Apr 2009) Log Message: ----------- Merged revisions 6168,6176,6186,6190-6192,6195-6197,6199-6202,6215-6217,6222-6223,6227-6228,6231,6237-6240 via svnmerge from https://jython.svn.sourceforge.net/svnroot/jython/branches/newlist Replaces PyList with a java.util.List and PyTuple with PyObject[] backed representations, respectively. Modified Paths: -------------- trunk/jython/Lib/test/test_javalist.py trunk/jython/src/org/python/core/JavaImportHelper.java trunk/jython/src/org/python/core/Py.java trunk/jython/src/org/python/core/PyList.java trunk/jython/src/org/python/core/PySequenceList.java trunk/jython/src/org/python/core/PyTuple.java trunk/jython/src/org/python/core/packagecache/PackageManager.java trunk/jython/src/templates/README.txt Added Paths: ----------- trunk/jython/src/org/python/core/PyComparator.java trunk/jython/src/templates/newtuple.derived Removed Paths: ------------- trunk/jython/src/org/python/core/PyObjectArray.java trunk/jython/src/org/python/core/PyObjectList.java Property Changed: ---------------- trunk/jython/ Property changes on: trunk/jython ___________________________________________________________________ Modified: svnmerge-integrated - /branches/modjy:1-6074 /branches/pbcvm:1-6045 /branches/newlist:1-6160 + /branches/modjy:1-6074 /branches/pbcvm:1-6045 /branches/newlist:1-6243 Modified: trunk/jython/Lib/test/test_javalist.py =================================================================== --- trunk/jython/Lib/test/test_javalist.py 2009-04-18 23:32:59 UTC (rev 6243) +++ trunk/jython/Lib/test/test_javalist.py 2009-04-19 00:01:11 UTC (rev 6244) @@ -1,4 +1,3 @@ -from test_support import * from javatests import ListTest class PyListTest(ListTest): Modified: trunk/jython/src/org/python/core/JavaImportHelper.java =================================================================== --- trunk/jython/src/org/python/core/JavaImportHelper.java 2009-04-18 23:32:59 UTC (rev 6243) +++ trunk/jython/src/org/python/core/JavaImportHelper.java 2009-04-19 00:01:11 UTC (rev 6244) @@ -120,6 +120,9 @@ Iterator iterator = ((PyTuple) fromlist).iterator(); while (iterator.hasNext()) { Object obj = iterator.next(); + if (obj instanceof PyString) { + obj = ((PyString)obj).string; + } if (obj instanceof String) { String fromName = (String) obj; if (!"*".equals(fromName)) { Modified: trunk/jython/src/org/python/core/Py.java =================================================================== --- trunk/jython/src/org/python/core/Py.java 2009-04-18 23:32:59 UTC (rev 6243) +++ trunk/jython/src/org/python/core/Py.java 2009-04-19 00:01:11 UTC (rev 6244) @@ -21,6 +21,8 @@ import org.python.antlr.base.mod; import com.kenai.constantine.platform.Errno; +import java.util.ArrayList; +import java.util.List; import org.python.compiler.Module; import org.python.core.adapter.ClassicPyObjectAdapter; import org.python.core.adapter.ExtensiblePyObjectAdapter; @@ -1932,13 +1934,12 @@ } catch (PyException exc) { } - PyObjectArray objs = new PyObjectArray(n); + List<PyObject> objs = new ArrayList<PyObject>(n); for (PyObject item : o.asIterable()) { objs.add(item); } - // Cut back if guess was too large. - objs.trimToSize(); - return (PyObject[]) objs.getArray(); + PyObject dest[] = new PyObject[0]; + return (objs.toArray(dest)); } } /** @deprecated */ Copied: trunk/jython/src/org/python/core/PyComparator.java (from rev 6202, branches/newlist/src/org/python/core/PyComparator.java) =================================================================== --- trunk/jython/src/org/python/core/PyComparator.java (rev 0) +++ trunk/jython/src/org/python/core/PyComparator.java 2009-04-19 00:01:11 UTC (rev 6244) @@ -0,0 +1,53 @@ +package org.python.core; + +import java.util.Comparator; + +public class PyComparator implements Comparator<PyObject> { + + protected PyList list; + protected PyObject cmp; + protected PyObject key; + protected boolean reverse = false; + + PyComparator(PyList list, PyObject cmp, PyObject key, boolean reverse) { + this.list = list; + this.cmp = cmp; + this.key = key; + this.reverse = reverse; + } + + // First cut at an implementation. FIXME: In CPython key is supposed to + // make things fast, accessing each element once. For this first cut I am + // cheating and calling the key function on every pass to get something + // that works right away. + public int compare(PyObject o1, PyObject o2) { + int result; + if (key != null && key != Py.None) { + o1 = key.__call__(o1); + o2 = key.__call__(o2); + } + if (cmp != null && cmp != Py.None) { + result = cmp.__call__(o1, o2).asInt(); + } else { + result = o1._cmp(o2); + } + if (reverse) { + return -result; + } + if (this.list.gListAllocatedStatus >= 0) { + throw Py.ValueError("list modified during sort"); + } + return result; + } + + public boolean equals(Object o) { + if(o == this) { + return true; + } + + if (o instanceof PyComparator) { + return key.equals(((PyComparator)o).key) && cmp.equals(((PyComparator)o).cmp); + } + return false; + } +} Modified: trunk/jython/src/org/python/core/PyList.java =================================================================== --- trunk/jython/src/org/python/core/PyList.java 2009-04-18 23:32:59 UTC (rev 6243) +++ trunk/jython/src/org/python/core/PyList.java 2009-04-19 00:01:11 UTC (rev 6244) @@ -1,38 +1,59 @@ // Copyright (c) Corporation for National Research Initiatives package org.python.core; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; - +import java.util.ArrayList; +import java.util.Arrays; import org.python.expose.ExposedMethod; import org.python.expose.ExposedNew; import org.python.expose.ExposedType; import org.python.expose.MethodType; import org.python.util.Generic; -/** - * A builtin python list. - */ +import java.util.Collection; +import java.util.Collections; +import java.util.ConcurrentModificationException; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; + @ExposedType(name = "list", base = PyObject.class) -public class PyList extends PySequenceList { +public class PyList extends PySequenceList implements List { public static final PyType TYPE = PyType.fromClass(PyList.class); + protected final List<PyObject> list; public PyList() { - this(TYPE, Py.EmptyObjects); + this(TYPE); } public PyList(PyType type) { super(type); + list = Generic.list(); } + private PyList(List list, boolean convert) { + super(TYPE); + if (!convert) { + this.list = list; + } else { + this.list = Generic.list(); + for (Object o : list) { + add(o); + } + } + } + public PyList(PyType type, PyObject[] elements) { - super(type, elements); + super(type); + list = new ArrayList<PyObject>(Arrays.asList(elements)); } public PyList(PyType type, Collection c) { - super(type, c); + super(type); + list = new ArrayList<PyObject>(c.size()); + for (Object o : c) { + add(o); + } } public PyList(PyObject[] elements) { @@ -40,23 +61,28 @@ } public PyList(Collection c) { - super(TYPE, c); + this(TYPE, c); } public PyList(PyObject o) { this(TYPE); for (PyObject item : o.asIterable()) { - append(item); + list.add(item); } } + public static PyList fromList(List<PyObject> list) { + return new PyList(list, false); + } + private static List<PyObject> listify(Iterator<PyObject> iter) { - List<PyObject> list = Generic.list(); - while (iter.hasNext()) { + List<PyObject> list = Generic.list(); + while (iter.hasNext()) { list.add(iter.next()); - } - return list; + } + return list; } + public PyList(Iterator<PyObject> iter) { this(TYPE, listify(iter)); } @@ -64,15 +90,16 @@ @ExposedNew @ExposedMethod(doc = BuiltinDocs.list___init___doc) final void list___init__(PyObject[] args, String[] kwds) { - ArgParser ap = new ArgParser("list", args, kwds, new String[] {"sequence"}, 0); + ArgParser ap = new ArgParser("list", args, kwds, new String[]{"sequence"}, 0); PyObject seq = ap.getPyObject(0, null); clear(); - if(seq == null) { + if (seq == null) { return; } - if(seq instanceof PySequenceList) { - PySequenceList p = (PySequenceList)seq.__getslice__(Py.None, Py.None, Py.One); - this.list = p.list; + if (seq instanceof PyList) { + list.addAll(((PyList) seq).list); // don't convert + } else if (seq instanceof PyTuple) { + list.addAll(((PyTuple) seq).getList()); } else { for (PyObject item : seq.asIterable()) { append(item); @@ -80,6 +107,7 @@ } } + @Override public int __len__() { return list___len__(); } @@ -89,105 +117,92 @@ return size(); } - protected PyObject getslice(int start, int stop, int step) { - if(step > 0 && stop < start) { - stop = start; - } - int n = sliceLength(start, stop, step); - PyObject[] newList = new PyObject[n]; - PyObject[] array = getArray(); - if(step == 1) { - System.arraycopy(array, start, newList, 0, stop - start); - return new PyList(newList); - } - int j = 0; - for(int i = start; j < n; i += step) { - newList[j] = array[i]; - j++; - } - return new PyList(newList); - } - + @Override protected void del(int i) { remove(i); } + @Override protected void delRange(int start, int stop) { remove(start, stop); } + @Override protected void setslice(int start, int stop, int step, PyObject value) { - if(stop < start) { + if (stop < start) { stop = start; } - if(value instanceof PySequence) { - PySequence sequence = (PySequence) value; - setslicePySequence(start, stop, step, sequence); - } else if(value instanceof List) { - List list = (List)value.__tojava__(List.class); - if(list != null && list != Py.NoConversion) { - setsliceList(start, stop, step, list); + if (value instanceof PyList) { + if (value == this) { // copy + value = new PyList((PySequence) value); } + setslicePyList(start, stop, step, (PyList) value); + } else if (value instanceof PySequence) { + setsliceIterator(start, stop, step, value.asIterable().iterator()); + } else if (value != null && !(value instanceof List)) { + value = new PyList(value); + setsliceIterator(start, stop, step, value.asIterable().iterator()); } else { - setsliceIterable(start, stop, step, value); + List valueList = (List) value.__tojava__(List.class); + if (valueList != null && valueList != Py.NoConversion) { + setsliceList(start, stop, step, valueList); + } } } - protected void setslicePySequence(int start, int stop, int step, PySequence value) { - if(step == 1) { - PyObject[] otherArray; - PyObject[] array = getArray(); + protected void setsliceList(int start, int stop, int step, List value) { + int n = sliceLength(start, stop, step); + if (list instanceof ArrayList) { + ((ArrayList) list).ensureCapacity(start + n); + } + ListIterator src = value.listIterator(); + for (int j = start; src.hasNext(); j += step) { + set(j, src.next()); + } + } - int n = value.__len__(); - if (value instanceof PySequenceList) { - otherArray = ((PySequenceList)value).getArray(); - } else { - otherArray = Py.unpackSequence(value, value.__len__()); + protected void setsliceIterator(int start, int stop, int step, Iterator<PyObject> iter) { + if (step == 1) { + List<PyObject> insertion = new ArrayList<PyObject>(); + if (iter != null) { + while (iter.hasNext()) { + insertion.add(iter.next()); + } } - if (otherArray == array) { - otherArray = otherArray.clone(); - } - list.replaceSubArray(start, stop, otherArray, 0, n); - } else if(step != 0) { - if(value == this) { - PyList newseq = new PyList(); - PyObject iter = value.__iter__(); - for(PyObject item = null; (item = iter.__iternext__()) != null;) { - newseq.append(item); + list.subList(start, stop).clear(); + list.addAll(start, insertion); + } else { + int size = list.size(); + for (int j = start; iter.hasNext(); j += step) { + PyObject item = iter.next(); + if (j >= size) { + list.add(item); + } else { + list.set(j, item); } - value = newseq; } - int n = value.__len__(); - for (int i = 0, j = start; i < n; i++, j += step) { - list.pyset(j, value.pyget(i)); - } } } - protected void setsliceList(int start, int stop, int step, List value) { - if(step != 1) { - throw Py.TypeError("setslice with java.util.List and step != 1 not supported yet"); - } - int n = value.size(); - list.ensureCapacity(start + n); - for(int i = 0; i < n; i++) { - list.add(i + start, value.get(i)); - } - } - - protected void setsliceIterable(int start, int stop, int step, PyObject value) { - PyObject[] seq; - try { - seq = Py.make_array(value); - } catch (PyException pye) { - if (Py.matchException(pye, Py.TypeError)) { - throw Py.TypeError("can only assign an iterable"); + protected void setslicePyList(int start, int stop, int step, PyList other) { + if (step == 1) { + list.subList(start, stop).clear(); + list.addAll(start, other.list); + } else { + int size = list.size(); + Iterator<PyObject> iter = other.list.listIterator(); + for (int j = start; iter.hasNext(); j += step) { + PyObject item = iter.next(); + if (j >= size) { + list.add(item); + } else { + list.set(j, item); + } } - throw pye; } - setslicePySequence(start, stop, step, new PyList(seq)); } + @Override protected PyObject repeat(int count) { if (count < 0) { count = 0; @@ -198,12 +213,11 @@ throw Py.MemoryError(""); } - PyObject[] array = getArray(); - PyObject[] newArray = new PyObject[newSize]; - for(int i = 0; i < count; i++) { - System.arraycopy(array, 0, newArray, i * size, size); + PyList newList = new PyList(); + for (int i = 0; i < count; i++) { + newList.addAll(list); } - return new PyList(newArray); + return newList; } @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.list___ne___doc) @@ -236,6 +250,7 @@ return seq___ge__(o); } + @Override public PyObject __imul__(PyObject o) { return list___imul__(o); } @@ -262,12 +277,14 @@ } int newSize = size * count; - list.setSize(newSize); - PyObject[] array = getArray(); + if (list instanceof ArrayList) { + ((ArrayList) list).ensureCapacity(newSize); + } + List oldList = new ArrayList<PyObject>(list); for (int i = 1; i < count; i++) { - System.arraycopy(array, 0, array, i * size, size); + list.addAll(oldList); } - gListAllocatedStatus = __len__(); + gListAllocatedStatus = __len__(); // now omit? return this; } @@ -297,6 +314,7 @@ return repeat(o.asIndex(Py.OverflowError)); } + @Override public PyObject __add__(PyObject o) { return list___add__(o); } @@ -304,22 +322,22 @@ @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.list___add___doc) final PyObject list___add__(PyObject o) { PyList sum = null; - if(o instanceof PyList) { - PyList other = (PyList)o; - int thisLen = size(); - int otherLen = other.size(); - PyObject[] newList = new PyObject[thisLen + otherLen]; - System.arraycopy(getArray(), 0, newList, 0, thisLen); - System.arraycopy(other.getArray(), 0, newList, thisLen, otherLen); - sum = new PyList(newList); - } else if(!(o instanceof PySequenceList)) { + if (o instanceof PySequenceList && !(o instanceof PyTuple)) { + if (o instanceof PyList) { + List oList = ((PyList) o).list; + List newList = new ArrayList(list.size() + oList.size()); + newList.addAll(list); + newList.addAll(oList); + sum = fromList(newList); + } + } else if (!(o instanceof PySequenceList)) { // also support adding java lists (but not PyTuple!) Object oList = o.__tojava__(List.class); - if(oList != Py.NoConversion && oList != null) { + if (oList != Py.NoConversion && oList != null) { List otherList = (List) oList; sum = new PyList(); sum.list_extend(this); - for(Iterator i = otherList.iterator(); i.hasNext();) { + for (Iterator i = otherList.iterator(); i.hasNext();) { sum.add(i.next()); } } @@ -327,6 +345,7 @@ return sum; } + @Override public PyObject __radd__(PyObject o) { return list___radd__(o); } @@ -335,9 +354,9 @@ @ExposedMethod(type = MethodType.BINARY) final PyObject list___radd__(PyObject o) { // Support adding java.util.List, but prevent adding PyTuple. - // 'o' should never be a PyList since __add__ is defined. + // 'o' should never be a PyNewList since __add__ is defined. PyList sum = null; - if(o instanceof PySequence) { + if (o instanceof PySequence) { return null; } Object oList = o.__tojava__(List.class); @@ -367,12 +386,13 @@ @ExposedMethod(doc = BuiltinDocs.list___getitem___doc) final PyObject list___getitem__(PyObject o) { PyObject ret = seq___finditem__(o); - if(ret == null) { + if (ret == null) { throw Py.IndexError("index out of range: " + o); } return ret; } + @Override public PyObject __iter__() { return list___iter__(); } @@ -397,8 +417,9 @@ seq___delslice__(start, stop, step); } + @Override protected String unsupportedopMessage(String op, PyObject o2) { - if(op.equals("+")) { + if (op.equals("+")) { return "can only concatenate list (not \"{2}\") to list"; } return super.unsupportedopMessage(op, o2); @@ -412,19 +433,19 @@ @ExposedMethod(names = "__repr__") final String list_toString() { ThreadState ts = Py.getThreadState(); - if(!ts.enterRepr(this)) { + if (!ts.enterRepr(this)) { return "[...]"; } StringBuilder buf = new StringBuilder("["); int length = size(); - PyObject[] array = getArray(); - for(int i = 0; i < length - 1; i++) { - buf.append((array[i]).__repr__().toString()); - buf.append(", "); + int i = 0; + for (PyObject item : list) { + buf.append(item.__repr__().toString()); + if (i < length - 1) { + buf.append(", "); + } + i++; } - if(length > 0) { - buf.append((array[length - 1]).__repr__().toString()); - } buf.append("]"); ts.exitRepr(this); return buf.toString(); @@ -459,9 +480,8 @@ @ExposedMethod(doc = BuiltinDocs.list_count_doc) final int list_count(PyObject o) { int count = 0; - PyObject[] array = getArray(); - for(int i = 0, n = size(); i < n; i++) { - if(array[i].equals(o)) { + for (PyObject item : list) { + if (item.equals(o)) { count++; } } @@ -509,10 +529,17 @@ // Follow Python 2.3+ behavior int validStop = boundToSequence(stop); int validStart = boundToSequence(start); - PyObject[] array = getArray(); - for(int i = validStart; i < validStop && i < size(); i++) { - if(array[i].equals(o)) { - return i; + int i = validStart; + if (validStart <= validStop) { + try { + for (PyObject item : list.subList(validStart, validStop)) { + if (item.equals(o)) { + return i; + } + i++; + } + } catch (ConcurrentModificationException ex) { + throw Py.ValueError(message); } } throw Py.ValueError(message); @@ -533,13 +560,13 @@ @ExposedMethod(doc = BuiltinDocs.list_insert_doc) final void list_insert(int index, PyObject o) { - if(index < 0) { + if (index < 0) { index = Math.max(0, size() + index); } - if(index > size()) { + if (index > size()) { index = size(); } - list.pyadd(index, o); + pyadd(index, o); gListAllocatedStatus = __len__(); } @@ -572,15 +599,7 @@ @ExposedMethod(doc = BuiltinDocs.list_reverse_doc) final void list_reverse() { - PyObject tmp; - int n = size(); - PyObject[] array = getArray(); - int j = n - 1; - for(int i = 0; i < n / 2; i++, j--) { - tmp = array[i]; - array[i] = array[j]; - array[j] = tmp; - } + Collections.reverse(list); gListAllocatedStatus = __len__(); } @@ -604,17 +623,16 @@ @ExposedMethod(defaults = "-1", doc = BuiltinDocs.list_pop_doc) final PyObject list_pop(int n) { int length = size(); - if(length == 0) { + if (length == 0) { throw Py.IndexError("pop from empty list"); } - if(n < 0) { + if (n < 0) { n += length; } - if(n < 0 || n >= length) { + if (n < 0 || n >= length) { throw Py.IndexError("pop index out of range"); } - PyObject v = pyget(n); - setslice(n, n + 1, 1, Py.EmptyTuple); + PyObject v = list.remove(n); return v; } @@ -631,11 +649,17 @@ @ExposedMethod(doc = BuiltinDocs.list_extend_doc) final void list_extend(PyObject o) { - int length = size(); - setslice(length, length, 1, o); + if (o instanceof PyList) { + list.addAll(((PyList) o).list); + } else { + for (PyObject item : o.asIterable()) { + list.add(item); + } + } gListAllocatedStatus = __len__(); } + @Override public PyObject __iadd__(PyObject o) { return list___iadd__(o); } @@ -672,13 +696,10 @@ * @param compare * the comparison function. */ - - /** + /** * Sort the items of the list in place. Items is compared with the normal relative comparison * operators. */ - - @ExposedMethod(doc = BuiltinDocs.list_sort_doc) final void list_sort(PyObject[] args, String[] kwds) { ArgParser ap = new ArgParser("list", args, kwds, new String[]{"cmp", "key", "reverse"}, 0); @@ -696,9 +717,11 @@ sort(Py.None, Py.None, Py.False); } - public void sort(PyObject cmp, PyObject key, PyObject reverse) { - MergeState ms = new MergeState(this, cmp, key, reverse.__nonzero__()); - ms.sort(); + public synchronized void sort(PyObject cmp, PyObject key, PyObject reverse) { + gListAllocatedStatus = -1; + PyComparator c = new PyComparator(this, cmp, key, reverse.__nonzero__()); + Collections.sort(list, c); + gListAllocatedStatus = __len__(); } public int hashCode() { @@ -710,7 +733,249 @@ throw Py.TypeError(String.format("unhashable type: '%.200s'", getType().fastGetName())); } + @Override public PyTuple __getnewargs__() { - return new PyTuple(new PyTuple(list.getArray())); + return new PyTuple(new PyTuple(getArray())); } + + @Override + public void add(int index, Object element) { + pyadd(index, Py.java2py(element)); + } + + @Override + public boolean add(Object o) { + pyadd(Py.java2py(o)); + return true; + } + + @Override + public boolean addAll(int index, Collection c) { + PyList elements = new PyList(c); + return list.addAll(index, elements.list); + } + + @Override + public boolean addAll(Collection c) { + return addAll(0, c); + } + + @Override + public void clear() { + list.clear(); + } + + @Override + public boolean contains(Object o) { + return list.contains(Py.java2py(o)); + } + + @Override + public boolean containsAll(Collection c) { + if (c instanceof PySequenceList) { + return list.containsAll(c); + } else { + return list.containsAll(new PyList(c)); + } + } + + @Override + public boolean equals(Object o) { + if (o instanceof PyList) { + return (((PyList) o).list.equals(list)); + } else if (o instanceof List) { // XXX copied from PyList, but... + return o.equals(this); // XXX shouldn't this compare using py2java? + } + return false; + } + + @Override + public Object get(int index) { + return list.get(index).__tojava__(Object.class); + } + + /** @deprecated */ + @Override + public PyObject[] getArray() { + PyObject a[] = null; // = new PyObject[list.size()]; + return list.toArray(a); + } + + @Override + public int indexOf(Object o) { + return list.indexOf(o); + } + + @Override + public boolean isEmpty() { + return list.isEmpty(); + } + + @Override + public Iterator iterator() { + return list.iterator(); + } + + @Override + public int lastIndexOf(Object o) { + return list.lastIndexOf(Py.java2py(o)); + } + + @Override + public ListIterator listIterator() { + return listIterator(0); + } + + @Override + public ListIterator listIterator(final int index) { + return new ListIterator() { + + private final ListIterator<PyObject> iter = list.listIterator(index); + + public boolean hasNext() { + return iter.hasNext(); + } + + public Object next() { + return iter.next().__tojava__(Object.class); + } + + public boolean hasPrevious() { + return iter.hasPrevious(); + } + + public Object previous() { + return iter.previous().__tojava__(Object.class); + } + + public int nextIndex() { + return iter.nextIndex(); + } + + public int previousIndex() { + return iter.previousIndex(); + } + + public void remove() { + iter.remove(); + } + + public void set(Object o) { + iter.set(Py.java2py(o)); + } + + public void add(Object o) { + iter.add(Py.java2py(o)); + } + }; + } + + @Override + public void pyadd(int index, PyObject element) { + list.add(index, element); + } + + @Override + public boolean pyadd(PyObject o) { + list.add(o); + return true; + } + + @Override + public PyObject pyget(int index) { + return list.get(index); + } + + public void pyset(int index, PyObject element) { + list.set(index, element); + } + + @Override + public Object remove(int index) { + return list.remove(index); + } + + @Override + public void remove(int start, int stop) { + list.subList(start, stop).clear(); + } + + @Override + public boolean removeAll(Collection c) { + if (c instanceof PySequenceList) { + return list.removeAll(c); + } else { + return list.removeAll(new PyList(c)); + } + } + + @Override + public boolean retainAll(Collection c) { + if (c instanceof PySequenceList) { + return list.retainAll(c); + } else { + return list.retainAll(new PyList(c)); + } + } + + @Override + public Object set(int index, Object element) { + return list.set(index, Py.java2py(element)).__tojava__(Object.class); + } + + @Override + public int size() { + return list.size(); + } + + @Override + public List subList(int fromIndex, int toIndex) { + return fromList(list.subList(fromIndex, toIndex)); + } + + @Override + public Object[] toArray() { + Object copy[] = list.toArray(); + for (int i = 0; i < copy.length; i++) { + copy[i] = ((PyObject) copy[i]).__tojava__(Object.class); + } + return copy; + } + + @Override + public Object[] toArray(Object[] a) { + Object copy[] = list.toArray(); + if (a.length != copy.length) { + a = copy; + } + for (int i = 0; i < copy.length; i++) { + a[i] = ((PyObject) copy[i]).__tojava__(Object.class); + } + for (int i = copy.length; i < a.length; i++) { + a[i] = null; + } + return a; + } + + protected PyObject getslice(int start, int stop, int step) { + if (step > 0 && stop < start) { + stop = start; + } + int n = sliceLength(start, stop, step); + List newList; + if (step == 1) { + newList = new ArrayList<PyObject>(list.subList(start, stop)); + } else { + newList = new ArrayList<PyObject>(n); + for (int i = start, j = 0; j < n; i += step, j++) { + newList.add(list.get(i)); + } + } + return fromList(newList); + } + + @Override + public boolean remove(Object o) { + return list.remove(Py.java2py(o)); + } } Deleted: trunk/jython/src/org/python/core/PyObjectArray.java =================================================================== --- trunk/jython/src/org/python/core/PyObjectArray.java 2009-04-18 23:32:59 UTC (rev 6243) +++ trunk/jython/src/org/python/core/PyObjectArray.java 2009-04-19 00:01:11 UTC (rev 6244) @@ -1,213 +0,0 @@ -//Copyright (c) Corporation for National Research Initiatives -package org.python.core; - - -/** - * Provides mutable behavior on a PyObject array. Supports operations for - * implementing <CODE>java.util.List</CODE>. - * @author Clark Updike - */ -public class PyObjectArray extends AbstractArray { - - public void remove(int start, int stop) { - super.remove(start, stop); - } - - /** - * The underlying array used for storing the data. - */ - protected PyObject[] baseArray; - - /** - * Create the array with the specified size. - */ - public PyObjectArray() { - super(PyObject.class); - } - - public PyObjectArray(PyObject[] rawArray) { - super(rawArray == null ? 0 : rawArray.length); - baseArray = (rawArray == null) ? new PyObject[] {} : rawArray; - } - - /** - * Create the array with the specified size. - * @param size number of int values initially allowed in array - */ - public PyObjectArray(int size) { - super(PyObject.class, size); - } - - /** - * @param toCopy - */ - public PyObjectArray(PyObjectArray toCopy) { - - super(toCopy); - this.baseArray = (PyObject[])toCopy.copyArray(); - } - - /** - * Add a value at a specified index in the array. - * <P><CODE>AbstractList</CODE> subclasses should update their - * <CODE>modCount</CODE> after calling this method. - * - * @param index index position at which to insert element - * @param value value to be inserted into array - */ - public void add(int index, PyObject value) { - makeInsertSpace(index); - baseArray[index] = value; - } - - /** - * Add a value to the array, appending it after the current values. - * <P><CODE>AbstractList</CODE> subclasses should update their - * <CODE>modCount</CODE> after calling this method. - * - * @param value value to be added - * @return index number of added element - */ - public int add(PyObject value) { - int index = getAddIndex(); - baseArray[index] = value; - return index; - } - - /** - * Duplicates the object with the generic call. - * - * @return a copy of the object - */ - public Object clone() { - return new PyObjectArray(this); - } - - public boolean equals(Object o) { - if(o instanceof PyObjectArray) { - PyObjectArray arr = (PyObjectArray)o; - if (size != arr.size) return false; - for (int i = 0; i < size; i++) { - PyObject thisElem = baseArray[i]; - PyObject otherElem = arr.baseArray[i]; - if (thisElem == null) { - if (otherElem == null) continue; - return false; - } - if (!thisElem.equals(otherElem)) return false; - } - return true; - } - return false; - } - - public int hashCode() { - int x, y; - int len = size; - x = 0x345678; - - for (len--; len>=0; len--) { - y = baseArray[len].hashCode(); - x = (x + x + x) ^ y; - } - x ^= size; - return x; - } - - /** - * Discards values for a range of indices from the array. For the array of - * <code>int</code> values, just sets the values to null. - * - * @param from index of first value to be discarded - * @param to index past last value to be discarded - */ - protected void discardValues(int from, int to) { - for (int i = from; i < to; i++) { - baseArray[i] = null; - } - } - - /** - * Retrieve the value present at an index position in the array. - * - * @param index index position for value to be retrieved - * @return value from position in the array - */ - public PyObject get(int index) { - - if (index >= 0 && index < size) { - return baseArray[index]; - } - - String message = (size == 0) - ? "No data was added, unable to get entry at " + index - : "Index must be between " + 0 + " and " + - (size - 1) + ", but was " + index; - throw new ArrayIndexOutOfBoundsException(message); - - } - - /** - * Get the backing array. This method is used by the type-agnostic base - * class code to access the array used for type-specific storage. The array - * should generally not be modified. To get a copy of the array, see - * {@link #toArray()} which returns a copy. Note that - * <CODE>getSize()</CODE> should be used to determine the number of elements - * in the array, not the array's length (which may reflect excess capacity). - * <CODE>toArray()</CODE> returns an array whose length equals the value - * returned by <CODE>getSize()</CODE>. - * - * @return backing array object - */ - public Object getArray() { - return baseArray; - } - - /** - * Set the value at an index position in the array. - * - * @param index index position to be set - * @param value value to be set - */ - public PyObject set(int index, PyObject value) { - if (index >= 0 && index < size) { - PyObject existing = baseArray[index]; - baseArray[index] = value; - return existing; - } - throw new ArrayIndexOutOfBoundsException( - "Index must be between " + 0 + " and " + - (size - 1) + ", but was " + index); - } - - /** - * Set the backing array. This method is used by the type-agnostic base - * class code to set the array used for type-specific storage. - * - * @param array the backing array object - */ - protected void setArray(Object array) { - baseArray = (PyObject[]) array; - } - - /** - * Constructs and returns a simple array containing the same data as held - * in this growable array. The array's length matches the value returned - * by <CODE>getSize()</CODE> - * - * @return array containing a copy of the data - */ - public PyObject[] toArray() { - return (PyObject[]) copyArray(); - } - - public void ensureCapacity(int minCapacity) { - super.ensureCapacity(minCapacity); - } - - @Override - protected PyObject[] createArray(int size) { - return new PyObject[size]; - } -} - Deleted: trunk/jython/src/org/python/core/PyObjectList.java =================================================================== --- trunk/jython/src/org/python/core/PyObjectList.java 2009-04-18 23:32:59 UTC (rev 6243) +++ trunk/jython/src/org/python/core/PyObjectList.java 2009-04-19 00:01:11 UTC (rev 6244) @@ -1,186 +0,0 @@ -//Copyright (c) Corporation for National Research Initiatives -package org.python.core; - -import java.io.Serializable; -import java.util.AbstractList; -import java.util.Collection; -import java.util.RandomAccess; - -/** - * <CODE>java.util.List</CODE> implementation using an underlying PyObject - * array for higher performance. Jython should use the following methods - * where possible, instead of their <CODE>List</CODE> counterparts: - * <UL> - * <LI>pyadd(int, PyObject)</LI> - * <LI>pyadd(PyObject)</LI> - * <LI>pyset(PyObject)</LI> - * <LI>pyget()</LI> - * </UL> - * @author Clark Updike - */ -public class PyObjectList - extends AbstractList<Object> implements RandomAccess, Cloneable, Serializable { - - /* - * Design note: This class lets PySequenceList implement java.util.List by delegating to it. The - * major distinction is that the backing array is PyObject[], not Object[] (as you'd get by - * delegating to ArrayList). There are 2 major benefits: 1) A lot of casting can be avoided - * internally (although use of PySequenceList descendants as java collections does involve some - * casting); 2) PySequenceList descendants can still do bulk array operations, allowing better - * performance and reuse of much of the pre-collections bulk operation implementation. - */ - - - /** - * Provides mutable operations on a PyObject[] array, including features - * that help with implementing java.util.List. - */ - protected PyObjectArray array; - - public PyObjectList() { - array = new PyObjectArray(); - } - - public PyObjectList(PyObject[] pyObjArr) { - array = new PyObjectArray(pyObjArr); - array.baseArray = pyObjArr; - } - - public PyObjectList(Collection<PyObject> c) { - array = new PyObjectArray(); - array.appendArray(c.toArray()); - } - - public PyObjectList(int size) { - array = new PyObjectArray(size); - } - - /** - * For internal jython usage, use {@link #pyadd(int, PyObject)}. - */ - public void add(int index, Object element) { - pyadd(index, Py.java2py(element)); - } - - public void pyadd(int index, PyObject element) { - array.add(index, element); - modCount += array.getModCountIncr(); - } - - /** - * For internal jython usage, use {@link #pyadd(PyObject)}. - */ - public boolean add(Object o) { - pyadd(Py.java2py(o)); - return true; - } - - public boolean pyadd(PyObject o) { - array.add(o); - modCount += array.getModCountIncr(); - return true; - } - - public Object clone(){ - try { - PyObjectList tol = (PyObjectList) super.clone(); - tol.array = (PyObjectArray) array.clone(); - tol.modCount = 0; - return tol; - } catch (CloneNotSupportedException eCNSE) { - throw new InternalError("Unexpected CloneNotSupportedException.\n" - + eCNSE.getMessage()); - } - } - - public boolean equals(Object o) { - if(o instanceof PyObjectList) { - return array.equals(((PyObjectList)o).array); - } - return false; - } - - public int hashCode() { - return array.hashCode(); - } - - /** - * Use <code>pyget(int)</code> for internal jython usage. - */ - public Object get(int index) { - return array.get(index).__tojava__(Object.class); - } - - PyObject pyget(int index) { - return array.get(index); - } - - public Object remove(int index) { - modCount++; - Object existing = array.get(index); - array.remove(index); - return existing; - } - - public void remove(int start, int stop) { - modCount++; - array.remove(start, stop); - } - - /** - * Use <code>pyset(int, PyObject)</code> for internal jython usage. - */ - public Object set(int index, Object element) { - return pyset(index, Py.java2py(element)).__tojava__(Object.class); - } - - PyObject pyset(int index, PyObject element) { - return array.set(index, element); - } - - public int size() { - return array.getSize(); - } - - public boolean addAll(Collection<? extends Object> c) { - return addAll(size(), c); - } - - public boolean addAll(int index, Collection<? extends Object> c) { - if (c instanceof PySequenceList) { - PySequenceList cList = (PySequenceList)c; - PyObject[] cArray = cList.getArray(); - int cOrigSize = cList.size(); - array.makeInsertSpace(index, cOrigSize); - array.replaceSubArray(index, index + cOrigSize, cArray, 0, cOrigSize); - } else { - // need to use add to convert anything pulled from a collection into a PyObject - for (Object element : c) { - add(element); - } - } - return c.size() > 0; - } - - /** - * Get the backing array. The array should generally not be modified. To get a copy of the - * array, see {@link #toArray()} which returns a copy. - * - * @return backing array object - */ - protected PyObject[] getArray() { - return (PyObject[])array.getArray(); - } - - void ensureCapacity(int minCapacity) { - array.ensureCapacity(minCapacity); - } - - void replaceSubArray(int destStart, int destStop, Object srcArray, int srcStart, int srcStop) { - array.replaceSubArray(destStart, destStop, srcArray, srcStart, srcStop); - } - - void setSize(int count) { - array.setSize(count); - } -} Modified: trunk/jython/src/org/python/core/PySequenceList.java =================================================================== --- trunk/jython/src/org/python/core/PySequenceList.java 2009-04-18 23:32:59 UTC (rev 6243) +++ trunk/jython/src/org/python/core/PySequenceList.java 2009-04-19 00:01:11 UTC (rev 6244) @@ -5,171 +5,81 @@ import java.util.List; import java.util.ListIterator; -public abstract class PySequenceList extends PySequence implements List { +public abstract class PySequenceList extends PySequence { - protected PyObjectList list; - public PySequenceList() { - list = new PyObjectList(); } protected PySequenceList(PyType type) { super(type); - list = new PyObjectList(); } - protected PySequenceList(PyType type, PyObject[] elements) { - super(type); - list = new PyObjectList(elements); - } + public abstract void add(int index, Object element); - /** - * Creates an instance directly backed by the array of PyObject elements. - */ - public PySequenceList(PyObject[] elements) { - list = new PyObjectList(elements); - } + public abstract boolean add(Object o); - public PySequenceList(PyType type, Collection<PyObject> c) { - super(type); - list = new PyObjectList(c); - } + public abstract boolean addAll(int index, Collection c); - public void add(int index, Object element) { - list.add(index, element); - } + public abstract boolean addAll(Collection c); - public boolean add(Object o) { - return list.add(o); - } + public abstract void clear(); - public boolean addAll(int index, Collection c) { - return list.addAll(index, c); - } + public abstract boolean contains(Object o); - public boolean addAll(Collection c) { - return list.addAll(c); - } + public abstract boolean containsAll(Collection c); - public void clear() { - list.clear(); - } + public abstract boolean equals(Object o); - public boolean contains(Object o) { - return list.contains(o); - } + public abstract Object get(int index); - public boolean containsAll(Collection c) { - return list.containsAll(c); - } + /** + * Get the backing array. The array should not be modified. To get a copy of the array, see + * {@link #toArray()}. + */ + public abstract PyObject[] getArray(); - public Object get(int index) { - return list.get(index); - } + public abstract int hashCode(); - public int indexOf(Object o) { - return list.indexOf(o); - } + public abstract int indexOf(Object o); - public boolean isEmpty() { - return list.isEmpty(); - } + public abstract boolean isEmpty(); - public Iterator iterator() { - return list.iterator(); - } + public abstract Iterator iterator(); - public int lastIndexOf(Object o) { - return list.lastIndexOf(o); - } + public abstract int lastIndexOf(Object o); - public ListIterator listIterator() { - return list.listIterator(); - } + public abstract ListIterator listIterator(); - public ListIterator listIterator(int index) { - return list.listIterator(index); - } + public abstract ListIterator listIterator(int index); - public void pyadd(int index, PyObject element) { - list.pyadd(index, element); - } + public abstract void pyadd(int index, PyObject element); - public PyObject pyget(int index) { - return list.pyget(index); - } + public abstract boolean pyadd(PyObject o); - public void pyset(int index, PyObject element) { - list.pyset(index, element); - } + public abstract PyObject pyget(int index); - public Object remove(int index) { - return list.remove(index); - } + public abstract void pyset(int index, PyObject element); - public void remove(int start, int stop) { - list.remove(start, stop); - } + public abstract Object remove(int index); - public boolean remove(Object o) { - return list.remove(o); - } + public abstract void remove(int start, int stop); - public boolean removeAll(Collection c) { - return list.removeAll(c); - } + public abstract boolean remove(Object o); - public boolean retainAll(Collection c) { - return list.retainAll(c); - } + public abstract boolean removeAll(Collection c); - public Object set(int index, Object element) { - return list.set(index, element); - } + public abstract boolean retainAll(Collection c); - public int size() { - return list.size(); - } + public abstract Object set(int index, Object element); - public List subList(int fromIndex, int toIndex) { - return list.subList(fromIndex, toIndex); - } + public abstract int size(); - public Object[] toArray() { - return list.toArray(); - } + public abstract List subList(int fromIndex, int toIndex); - public Object[] toArray(Object[] a) { - return list.toArray(a); - } + public abstract Object[] toArray(); - public String toString() { - return list.toString(); - } + public abstract Object[] toArray(Object[] a); - public boolean pyadd(PyObject o) { - return list.pyadd(o); - } + public abstract String toString(); - public boolean equals(Object o) { - if(o instanceof PySequenceList) { - return list.equals(((PySequenceList)o).list); - } else if(o instanceof List) { - return o.equals(this); - } else { - return super.equals(o); - } - } - - public int hashCode() { - return list.hashCode(); - } - - /** - * Get the backing array. The array should not be modified. To get a copy of the array, see - * {@link #toArray()}. - */ - public PyObject[] getArray() { - return list.getArray(); - } } Modified: trunk/jython/src/org/python/core/PyTuple.java =================================================================== --- trunk/jython/src/org/python/core/PyTuple.java 2009-04-18 23:32:59 UTC (rev 6243) +++ trunk/jython/src/org/python/core/PyTuple.java 2009-04-19 00:01:11 UTC (rev 6244) @@ -1,6 +1,7 @@ // Copyright (c) Corporation for National Research Initiatives package org.python.core; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Iterator; @@ -15,11 +16,12 @@ /** * A builtin python tuple. */ +@ExposedType(name = "tuple", base = PyObject.class) +public class PyTuple extends PySequenceList implements List { -@ExposedType(name = "tuple", base = PyObject.class) -public class PyTuple extends PySequenceList -{ public static final PyType TYPE = PyType.fromClass(PyTuple.class); + private final PyObject[] array; + private static final PyTuple EMPTY_TUPLE = new PyTuple(); public PyTuple() { this(TYPE, Py.EmptyObjects); @@ -30,25 +32,58 @@ } public PyTuple(PyType subtype, PyObject[] elements) { - super(subtype, elements); + super(subtype); + if (elements == null) { + array = new PyObject[0]; + } else { + array = new PyObject[elements.length]; + System.arraycopy(elements, 0, array, 0, elements.length); + } } + public PyTuple(PyObject[] elements, boolean copy) { + this(TYPE, elements, copy); + } + + public PyTuple(PyType subtype, PyObject[] elements, boolean copy) { + super(subtype); + + if (copy) { + array = new PyObject[elements.length]; + System.arraycopy(elements, 0, array, 0, elements.length); + } else { + array = elements; + } + } + + private static PyTuple fromArrayNoCopy(PyObject[] elements) { + return new PyTuple(elements, false); + } + private volatile List<PyObject> cachedList = null; + + List<PyObject> getList() { + if (cachedList == null) { + cachedList = Arrays.asList(array); + } + return cachedList; + } + @ExposedNew final static PyObject tuple_new(PyNewWrapper new_, boolean init, PyType subtype, PyObject[] args, String[] keywords) { - ArgParser ap = new ArgParser("tuple", args, keywords, new String[] { "sequence" }, 0); + ArgParser ap = new ArgParser("newtuple", args, keywords, new String[]{"sequence"}, 0); PyObject S = ap.getPyObject(0, null); if (new_.for_type == subtype) { if (S == null) { - return new PyTuple(); + return EMPTY_TUPLE; } if (S instanceof PyTupleDerived) { - return new PyTuple(((PyTuple)S).getArray()); + return new PyTuple(((PyTuple) S).getArray()); } if (S instanceof PyTuple) { return S; } - return new PyTuple(Py.make_array(S)); + return fromArrayNoCopy(Py.make_array(S)); } else { if (S == null) { return new PyTupleDerived(subtype, Py.EmptyObjects); @@ -66,26 +101,26 @@ * @return a PyTuple containing each item in the iterable */ public static PyTuple fromIterable(PyObject iterable) { - return new PyTuple(Py.make_array(iterable)); + return fromArrayNoCopy(Py.make_array(iterable)); } protected PyObject getslice(int start, int stop, int step) { - if (step > 0 && stop < start) + if (step > 0 && stop < start) { stop = start; + } int n = sliceLength(start, stop, step); PyObject[] newArray = new PyObject[n]; - PyObject[] array = getArray(); if (step == 1) { - System.arraycopy(array, start, newArray, 0, stop-start); - return new PyTuple(newArray); + System.arraycopy(array, start, newArray, 0, stop - start); + return fromArrayNoCopy(newArray); } int j = 0; - for (int i=start; j<n; i+=step) { + for (int i = start; j < n; i += step) { newArray[j] = array[i]; j++; } - return new PyTuple(newArray); + return fromArrayNoCopy(newArray); } protected PyObject repeat(int count) { @@ -99,7 +134,7 @@ return this; } if (size == 0) { - return new PyTuple(); + return EMPTY_TUPLE; } } @@ -108,14 +143,14 @@ throw Py.MemoryError(""); } - PyObject[] array = getArray(); PyObject[] newArray = new PyObject[newSize]; for (int i = 0; i < count; i++) { System.arraycopy(array, 0, newArray, i * size, size); } - return new PyTuple(newArray); + return fromArrayNoCopy(newArray); } + @Override public int __len__() { return tuple___len__(); } @@ -124,7 +159,7 @@ final int tuple___len__() { return size(); } - + @ExposedMethod(doc = BuiltinDocs.tuple___contains___doc) final boolean tuple___contains__(PyObject o) { return super.__contains__(o); @@ -160,6 +195,7 @@ return super.__le__(o); } + @Override public PyObject __add__(PyObject generic_other) { return tuple___add__(generic_other); } @@ -168,15 +204,11 @@ final PyObject tuple___add__(PyObject generic_other) { PyTuple sum = null; if (generic_other instanceof PyTuple) { - PyTuple otherTuple = (PyTuple)generic_other; - PyObject[] array = getArray(); - PyObject[] otherArray = otherTuple.getArray(); - int thisLen = size(); - int otherLen = otherTuple.size(); - PyObject[] newArray = new PyObject[thisLen + otherLen]; - System.arraycopy(array, 0, newArray, 0, thisLen); - System.arraycopy(otherArray, 0, newArray, thisLen, otherLen); - sum = new PyTuple(newArray); + PyTuple other = (PyTuple) generic_other; + PyObject[] newArray = new PyObject[array.length + other.array.length]; + System.arraycopy(array, 0, newArray, 0, array.length); + System.arraycopy(other.array, 0, newArray, array.length, other.array.length); + sum = fromArrayNoCopy(newArray); } return sum; } @@ -207,6 +239,7 @@ return repeat(o.asIndex(Py.OverflowError)); } + @Override public PyObject __iter__() { return tuple___iter__(); } @@ -218,13 +251,13 @@ @ExposedMethod(defaults = "null", doc = BuiltinDocs.tuple___getslice___doc) final PyObject tuple___getslice__(PyObject s_start, PyObject s_stop, PyObject s_step) { - return seq___getslice__(s_start,s_stop,s_step); + return seq___getslice__(s_start, s_stop, s_step); } @ExposedMethod(doc = BuiltinDocs.tuple___getitem___doc) final PyObject tuple___getitem__(PyObject index) { PyObject ret = seq___finditem__(index); - if(ret == null) { + if (ret == null) { throw Py.IndexError("index out of range: " + index); } return ret; @@ -232,13 +265,15 @@ @ExposedMethod(doc = BuiltinDocs.tuple___getnewargs___doc) final PyTuple tuple___getnewargs__() { - return new PyTuple(new PyTuple(list.getArray())); + return new PyTuple(new PyTuple(getArray())); } + @Override public PyTuple __getnewargs__() { return tuple___getnewargs__(); } + @Override public int hashCode() { return tuple___hash__(); } @@ -251,7 +286,6 @@ int len = size(); int mult = 1000003; int x = 0x345678; - PyObject[] array = getArray(); while (--len >= 0) { y = array[len].hashCode(); x = (x ^ y) * mult; @@ -261,11 +295,13 @@ } private String subobjRepr(PyObject o) { - if (o == null) + if (o == null) { return "null"; + } return o.__repr__().toString(); } + @Override public String toString() { return tuple___repr__(); } @@ -273,43 +309,54 @@ @ExposedMethod(doc = BuiltinDocs.tuple___repr___doc) final String tuple___repr__() { StringBuilder buf = new StringBuilder("("); - PyObject[] array = getArray(); - int arrayLen = size(); - for (int i = 0; i < arrayLen-1; i++) { + for (int i = 0; i < array.length - 1; i++) { buf.append(subobjRepr(array[i])); buf.append(", "); } - if (arrayLen > 0) - buf.append(subobjRepr(array[arrayLen-1])); - if (arrayLen == 1) + if (array.length > 0) { + buf.append(subobjRepr(array[array.length - 1])); + } + if (array.length == 1) { buf.append(","); + } buf.append(")"); return buf.toString(); } public List subList(int fromIndex, int toIndex) { - return Collections.unmodifiableList(list.subList(fromIndex, toIndex)); + if (fromIndex < 0 || toIndex > size()) { + throw new IndexOutOfBoundsException(); + } else if (fromIndex > toIndex) { + throw new IllegalArgumentException(); + } + System.err.println("subList" + fromIndex + "," + toIndex); + PyObject elements[] = new PyObject[toIndex - fromIndex]; + for (int i = 0, j = fromIndex; i < elements.length; i++, j++) { + elements[i] = array[j]; + } + return new PyTuple(elements); } - // Make PyTuple immutable from the collections interfaces by overriding - // all the mutating methods to throw UnsupportedOperationException exception. - // This is how Collections.unmodifiableList() does it. public Iterator iterator() { return new Iterator() { - Iterator i = list.iterator(); + + private final Iterator<PyObject> iter = getList().iterator(); + public void remove() { throw new UnsupportedOperationException(); } + public boolean hasNext() { ... [truncated message content] |