Repository: pymor/pymor

Issue:
Making VectorArrays iterable
There is already some work done in the `va_iteration` branch, modifying [`__getitem__`](https://docs.python.org/3/reference/datamodel.html#object.__getitem__) to raise `IndexError` for illegal indices.

Discussion:

Patch:
diff --git a/src/pymor/vectorarrays/list.py b/src/pymor/vectorarrays/list.py
index f2fe49a13..32e2397ed 100644
--- a/src/pymor/vectorarrays/list.py
+++ b/src/pymor/vectorarrays/list.py
@@ -392,6 +392,8 @@ class ListVectorArray(VectorArray):
         return len(self._list)
 
     def __getitem__(self, ind):
+        if isinstance(ind, Number) and (ind >= len(self) or ind < -len(self)):
+            raise IndexError('VectorArray index out of range')
         return ListVectorArrayView(self, ind)
 
     def __delitem__(self, ind):
@@ -724,7 +726,10 @@ class ListVectorArrayView(ListVectorArray):
         return self.base.space
 
     def __getitem__(self, ind):
-        return self.base[self.base.sub_index(self.ind, ind)]
+        try:
+            return self.base[self.base.sub_index(self.ind, ind)]
+        except IndexError:
+            raise IndexError('VectorArray index out of range')
 
     def __delitem__(self, ind):
         raise TypeError('Cannot remove from ListVectorArrayView')
diff --git a/src/pymor/vectorarrays/numpy.py b/src/pymor/vectorarrays/numpy.py
index 45d847630..1244e5961 100644
--- a/src/pymor/vectorarrays/numpy.py
+++ b/src/pymor/vectorarrays/numpy.py
@@ -68,6 +68,8 @@ class NumpyVectorArray(VectorArray):
         return self._len
 
     def __getitem__(self, ind):
+        if isinstance(ind, Number) and (ind >= self._len or ind < -self._len):
+            raise IndexError('VectorArray index out of range')
         return NumpyVectorArrayView(self, ind)
 
     def __delitem__(self, ind):
@@ -460,7 +462,10 @@ class NumpyVectorArrayView(NumpyVectorArray):
         return self.base.len_ind(self.ind)
 
     def __getitem__(self, ind):
-        return self.base[self.base.sub_index(self.ind, ind)]
+        try:
+            return self.base[self.base.sub_index(self.ind, ind)]
+        except IndexError:
+            raise IndexError('VectorArray index out of range')
 
     def __delitem__(self):
         raise ValueError('Cannot remove from NumpyVectorArrayView')


Test patch:
diff --git a/src/pymortests/vectorarray.py b/src/pymortests/vectorarray.py
index eb5e4601a..1b1c68269 100644
--- a/src/pymortests/vectorarray.py
+++ b/src/pymortests/vectorarray.py
@@ -932,6 +932,13 @@ def test_imul_wrong_factor(vector_array):
     with pytest.raises(Exception):
         vector_array *= vector_array
 
+@pyst.given_vector_arrays()
+def test_iter(vector_array):
+    v = vector_array
+    w = v.empty()
+    for vv in v:
+        w.append(vv)
+    assert np.all(almost_equal(w, v))
 
 ########################################################################################################################