Skip to content

Commit

Permalink
Remove cube iter (SciTools#3656)
Browse files Browse the repository at this point in the history
  • Loading branch information
jonseddon authored and tkknight committed Jun 29, 2020
1 parent c8ff9ca commit 59c085a
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 2 deletions.
3 changes: 3 additions & 0 deletions docs/iris/src/userguide/subsetting_a_cube.rst
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ same way as loading with constraints:

Cube iteration
^^^^^^^^^^^^^^^
It is not possible to directly iterate over an Iris cube. That is, you cannot use code such as
``for x in cube:``. However, you can iterate over cube slices, as this section details.

A useful way of dealing with a Cube in its **entirety** is by iterating over its layers or slices.
For example, to deal with a 3 dimensional cube (z,y,x) you could iterate over all 2 dimensional slices in y and x
which make up the full 3d cube.::
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
* The `__iter__()` method in class:`iris.cube.Cube` was set to `None`.
`TypeError` is still raised if a `Cube` is iterated over but
`isinstance(cube, collections.Iterable)` now behaves as expected.
5 changes: 3 additions & 2 deletions lib/iris/cube.py
Original file line number Diff line number Diff line change
Expand Up @@ -2622,8 +2622,9 @@ def _repr_html_(self):
representer = CubeRepresentation(self)
return representer.repr_html()

def __iter__(self):
raise TypeError("Cube is not iterable")
# Indicate that the iter option is not available. Python will raise
# TypeError with a useful message if a Cube is iterated over.
__iter__ = None

def __getitem__(self, keys):
"""
Expand Down
4 changes: 4 additions & 0 deletions lib/iris/tests/test_cdm.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
# import iris tests first so that some things can be initialised before importing anything else
import iris.tests as tests

import collections
import os
import re

Expand Down Expand Up @@ -690,6 +691,9 @@ def test_cube_iteration(self):
for subcube in self.t:
pass

def test_not_iterable(self):
self.assertFalse(isinstance(self.t, collections.Iterable))


class Test2dSlicing(TestCube2d):
def test_cube_slice_all_dimensions(self):
Expand Down
18 changes: 18 additions & 0 deletions lib/iris/tests/unit/cube/test_CubeList.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

# Import iris.tests first so that some things can be initialised before
# importing anything else.
import collections

import iris.tests as tests
import iris.tests.stock

Expand Down Expand Up @@ -292,6 +294,22 @@ def test_scalar_cube_data_constraint(self):
self.assertEqual(res, expected)


class Test_iteration(tests.IrisTest):
def setUp(self):
self.scalar_cubes = CubeList()
for i in range(5):
for letter in "abcd":
self.scalar_cubes.append(Cube(i, long_name=letter))

def test_iterable(self):
self.assertTrue(isinstance(self.scalar_cubes, collections.Iterable))

def test_iteration(self):
letters = "abcd" * 5
for i, cube in enumerate(self.scalar_cubes):
self.assertEqual(cube.long_name, letters[i])


class TestPrint(tests.IrisTest):
def setUp(self):
self.cubes = CubeList([iris.tests.stock.lat_lon_cube()])
Expand Down

0 comments on commit 59c085a

Please sign in to comment.