com.xiaopy.python.PyList Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of chaquopy_java Show documentation
Show all versions of chaquopy_java Show documentation
The Python SDK for Android
package com.xiaopy.python;
import java.util.*;
class PyList extends AbstractList {
private final PyObject obj;
private final MethodCache methods;
public PyList(PyObject obj) {
this.obj = obj;
methods = new MethodCache(obj);
methods.get("__getitem__");
methods.get("__len__");
}
// Python accepts negative indices, but the Java interface should reject them. We don't
// usually check the upper bound, because that would make a redundant call to `__len__`.
// Instead, the caller should catch IndexError.
private void checkLowerBound(int index) {
if (index < 0) {
throw outOfBounds(index);
}
}
private RuntimeException maybeOutOfBounds(int index, PyException e) {
if (e.getMessage().startsWith("IndexError:")) {
return outOfBounds(index);
} else {
return e;
}
}
private IndexOutOfBoundsException outOfBounds(int index) {
// Same wording as ArrayList exception.
return new IndexOutOfBoundsException(
"Invalid index " + index + ", size is " + size());
}
// === Read methods ======================================================
@Override public int size() {
return methods.get("__len__").call().toInt();
}
@Override public PyObject get(int index) {
checkLowerBound(index);
try {
return methods.get("__getitem__").call(index);
} catch (PyException e) {
throw maybeOutOfBounds(index, e);
}
}
// === Modification methods ==============================================
//
// Ideally `set` and `add` would be able to take any object, to save the user having to
// call PyObject.fromJava manually. But we can't replace or overload the methods with
// versions which take Object, because that causes the error "set(int,Object) in PyList and
// set(int,E) in AbstractList have the same erasure, yet neither overrides the other". It
// makes no difference whether we use AbstractList or implement List directly.
//
// We got away with this when overloading PyObject.put, because its key parameter is a
// String, not an Object, so it doesn't have the same erasure as the base class method in
// Map.
//
// I also tried the reverse approach of extending List
© 2015 - 2024 Weber Informatics LLC | Privacy Policy