Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions lib/iris/cube.py
Original file line number Diff line number Diff line change
Expand Up @@ -1240,6 +1240,16 @@ def __str__(self):
def __repr__(self):
return "<iris 'Cube' of %s>" % self.summary(shorten=True, name_padding=1)

def __iter__(self):
# Emit a warning about iterating over the cube.
# __getitem__ makes this possible, but now deprecated as confusing.
warnings.warn('Cube iteration has been deprecated: '
'please use Cube.slices() instead.')

# Return a simple first-index iterator, equivalent to that produced
# with __getitem__, if __iter__ was not defined.
return (self[i] for i in range(self.shape[0]))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does calling the super iter method not "just work"?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pelson Does calling the super iter method not "just work"?

Unfortunately no, because Cube derives from 'CFVariableMixin', which just inherits 'object'. Neither of these has an iter or a getitem, which are what '`iter()' looks for.
So the only way is to call Cube.getitem with consecutive indices, and raise 'StopIteration' when it raises an 'IndexError', or after counting up to cube.shape[0].

There may be a more 'ultimately efficient' way with itertools, but I cant find a nice one.
E.G. how about ..
itertools.islice(itertools.imap(lambda i: cube[i], itertools.count()), cube.shape[0])
??

I think the existing code reads clearer, anyway.


def __getitem__(self, keys):
"""
Cube indexing (through use of square bracket notation) has been implemented at the data level. That is,
Expand Down
15 changes: 15 additions & 0 deletions lib/iris/tests/test_cdm.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

import os
import re
import warnings

import numpy

Expand Down Expand Up @@ -503,6 +504,20 @@ def test_ellipsis(self):
self.assertCML([self.t[(0, 2), :, Ellipsis]], ('cube_slice', '2d_to_1d_cube_multi_slice3.cml'))


class TestIteration(TestCube2d):
def test_cube_iteration(self):
# Check that creating a cube iterator generates a warning.
with warnings.catch_warnings():
warnings.simplefilter('error')
with self.assertRaises(UserWarning):
for subcube in self.t: # warning->error, so this *fails*
pass
# Check we can step through the items, and their shape and number.
subcubes = [subcube for subcube in self.t]
self.assertEqual(len(subcubes), self.t.shape[0])
for subcube in subcubes:
self.assertEqual(subcube.shape, self.t.shape[1:])

class Test2dSlicing(TestCube2d):
def test_cube_slice_all_dimensions(self):
for cube in self.t.slices(['dim1', 'dim2']):
Expand Down