Skip to content

Commit

Permalink
Deprecate legacy_custom_rules
Browse files Browse the repository at this point in the history
  • Loading branch information
rhattersley committed Nov 16, 2015
1 parent 561071b commit d80abb9
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 9 deletions.
4 changes: 2 additions & 2 deletions lib/iris/fileformats/grib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -894,7 +894,7 @@ def load_cubes(filenames, callback=None, auto_regularise=True):
grib_loader = iris.fileformats.rules.Loader(
_GribMessage.messages_from_filename,
{},
iris.fileformats.grib._load_convert.convert, None)
iris.fileformats.grib._load_convert.convert)
else:
if auto_regularise is not None:
# The old loader supports the auto_regularise keyword, but in
Expand All @@ -907,7 +907,7 @@ def load_cubes(filenames, callback=None, auto_regularise=True):

grib_loader = iris.fileformats.rules.Loader(
grib_generator, {'auto_regularise': auto_regularise},
iris.fileformats.grib.load_rules.convert, None)
iris.fileformats.grib.load_rules.convert)
return iris.fileformats.rules.load_cubes(filenames, callback, grib_loader)


Expand Down
2 changes: 1 addition & 1 deletion lib/iris/fileformats/pp.py
Original file line number Diff line number Diff line change
Expand Up @@ -2035,7 +2035,7 @@ def _load_cubes_variable_loader(filenames, callback, loading_function,
pp_filter = _convert_constraints(constraints)
pp_loader = iris.fileformats.rules.Loader(
loading_function, loading_function_kwargs or {},
iris.fileformats.pp_rules.convert, None)
iris.fileformats.pp_rules.convert)
return iris.fileformats.rules.load_cubes(filenames, callback, pp_loader,
pp_filter)

Expand Down
40 changes: 37 additions & 3 deletions lib/iris/fileformats/rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -779,9 +779,41 @@ def _ensure_aligned(regrid_cache, src_cube, target_cube):
return result_cube


Loader = collections.namedtuple('Loader',
('field_generator', 'field_generator_kwargs',
'converter', 'legacy_custom_rules'))
_loader_attrs = ('field_generator', 'field_generator_kwargs',
'converter', 'legacy_custom_rules')
class Loader(collections.namedtuple('Loader', _loader_attrs)):
def __new__(cls, field_generator, field_generator_kwargs, converter,
legacy_custom_rules=None):
"""
Create a definition of a field-based Cube loader.
Args:
* field_generator
A callable that accepts a filename as its first argument and
returns an iterable of field objects.
* field_generator_kwargs
Additional arguments to be passed to the field_generator.
* converter
A callable that converts a field object into a Cube.
Kwargs:
* legacy_custom_rules
An object with a callable `verify` attribute with two
parameters: (cube, field). Legacy method for modifying
Cubes during the load process. Default is None.
.. deprecated:: 1.9
"""
if legacy_custom_rules is not None:
warnings.warn('The `legacy_custom_rules` attribute is '
'deprecated.')
return tuple.__new__(cls, (field_generator, field_generator_kwargs,
converter, legacy_custom_rules))


ConversionMetadata = collections.namedtuple('ConversionMetadata',
Expand Down Expand Up @@ -846,6 +878,8 @@ def load_cubes(filenames, user_callback, loader, filter_function=None):

# Run any custom user-provided rules.
if loader.legacy_custom_rules:
warnings.warn('The `legacy_custom_rules` attribute of '
'the `loader` is deprecated.')
loader.legacy_custom_rules.verify(cube, field)

cube = iris.io.run_callback(user_callback, cube, field, filename)
Expand Down
6 changes: 3 additions & 3 deletions lib/iris/tests/integration/test_pp_constrained_load_cubes.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def test_pp_with_stash_constraint(self):
filenames = [tests.get_data_path(('PP', 'globClim1', 'dec_subset.pp'))]
stcon = iris.AttributeConstraint(STASH='m01s00i004')
pp_constraints = pp._convert_constraints(stcon)
pp_loader = iris.fileformats.rules.Loader(pp.load, {}, convert, None)
pp_loader = iris.fileformats.rules.Loader(pp.load, {}, convert)
cubes = list(load_cubes(filenames, None, pp_loader, pp_constraints))
self.assertEqual(len(cubes), 38)

Expand All @@ -45,15 +45,15 @@ def test_pp_with_stash_constraints(self):
stcon1 = iris.AttributeConstraint(STASH='m01s00i004')
stcon2 = iris.AttributeConstraint(STASH='m01s00i010')
pp_constraints = pp._convert_constraints([stcon1, stcon2])
pp_loader = iris.fileformats.rules.Loader(pp.load, {}, convert, None)
pp_loader = iris.fileformats.rules.Loader(pp.load, {}, convert)
cubes = list(load_cubes(filenames, None, pp_loader, pp_constraints))
self.assertEqual(len(cubes), 76)

@tests.skip_data
def test_pp_no_constraint(self):
filenames = [tests.get_data_path(('PP', 'globClim1', 'dec_subset.pp'))]
pp_constraints = pp._convert_constraints(None)
pp_loader = iris.fileformats.rules.Loader(pp.load, {}, convert, None)
pp_loader = iris.fileformats.rules.Loader(pp.load, {}, convert)
cubes = list(load_cubes(filenames, None, pp_loader, pp_constraints))
self.assertEqual(len(cubes), 152)

Expand Down
73 changes: 73 additions & 0 deletions lib/iris/tests/unit/fileformats/rules/test_Loader.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# (C) British Crown Copyright 2015, Met Office
#
# This file is part of Iris.
#
# Iris is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the
# Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Iris is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Iris. If not, see <http://www.gnu.org/licenses/>.
"""Unit tests for :class:`iris.fileformats.rules.Loader`."""

from __future__ import (absolute_import, division, print_function)
from six.moves import (filter, input, map, range, zip) # noqa

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

import mock

from iris.fileformats.rules import Loader


class Test___init__(tests.IrisTest):
def test_normal(self):
with mock.patch('warnings.warn') as warn:
loader = Loader(mock.sentinel.GEN_FUNC,
mock.sentinel.GEN_FUNC_KWARGS,
mock.sentinel.CONVERTER)
self.assertEqual(warn.call_count, 0)
self.assertIs(loader.field_generator, mock.sentinel.GEN_FUNC)
self.assertIs(loader.field_generator_kwargs,
mock.sentinel.GEN_FUNC_KWARGS)
self.assertIs(loader.converter, mock.sentinel.CONVERTER)
self.assertIs(loader.legacy_custom_rules, None)

def test_normal_with_explicit_none(self):
with mock.patch('warnings.warn') as warn:
loader = Loader(mock.sentinel.GEN_FUNC,
mock.sentinel.GEN_FUNC_KWARGS,
mock.sentinel.CONVERTER, None)
self.assertEqual(warn.call_count, 0)
self.assertIs(loader.field_generator, mock.sentinel.GEN_FUNC)
self.assertIs(loader.field_generator_kwargs,
mock.sentinel.GEN_FUNC_KWARGS)
self.assertIs(loader.converter, mock.sentinel.CONVERTER)
self.assertIs(loader.legacy_custom_rules, None)

def test_deprecated_custom_rules(self):
with mock.patch('warnings.warn') as warn:
loader = Loader(mock.sentinel.GEN_FUNC,
mock.sentinel.GEN_FUNC_KWARGS,
mock.sentinel.CONVERTER,
mock.sentinel.CUSTOM_RULES)
self.assertEqual(warn.call_count, 1)
self.assertEqual(warn.call_args[0][0],
'The `legacy_custom_rules` attribute is deprecated.')
self.assertIs(loader.field_generator, mock.sentinel.GEN_FUNC)
self.assertIs(loader.field_generator_kwargs,
mock.sentinel.GEN_FUNC_KWARGS)
self.assertIs(loader.converter, mock.sentinel.CONVERTER)
self.assertIs(loader.legacy_custom_rules, mock.sentinel.CUSTOM_RULES)


if __name__ == '__main__':
tests.main()

0 comments on commit d80abb9

Please sign in to comment.