diff --git a/INSTALL b/INSTALL index 5a82044597..729de8d20f 100644 --- a/INSTALL +++ b/INSTALL @@ -132,7 +132,7 @@ mock 1.0.1 (http://pypi.python.org/pypi/mock/) nose 1.1.2 or later (https://nose.readthedocs.io/en/latest/) Python package for software testing. Iris is not compatible with nose2. -pep8 1.4.6* (https://pypi.python.org/pypi/pep8) +pep8 1.4.6 (https://pypi.python.org/pypi/pep8) Python package for software testing. pandas 0.11.0 or later (http://pandas.pydata.org) diff --git a/conda-requirements.txt b/conda-requirements.txt index f533a424dc..ade5ffd137 100644 --- a/conda-requirements.txt +++ b/conda-requirements.txt @@ -17,7 +17,7 @@ setuptools # Iris testing/documentation dependencies mock nose -pep8=1.5.7 +pep8 sphinx iris_sample_data filelock diff --git a/lib/iris/_concatenate.py b/lib/iris/_concatenate.py index 768ddf54c0..2da88f39d4 100644 --- a/lib/iris/_concatenate.py +++ b/lib/iris/_concatenate.py @@ -341,12 +341,13 @@ def __init__(self, cube): # Collate the auxiliary coordinate metadata and scalar coordinates. # axes = dict(T=0, Z=1, Y=2, X=3) + # Coordinate sort function - by guessed coordinate axis, then # by coordinate definition, then by dimensions, in ascending order. - key_func = lambda coord: (axes.get(guess_coord_axis(coord), - len(axes) + 1), - coord._as_defn(), - cube.coord_dims(coord)) + def key_func(coord): + return (axes.get(guess_coord_axis(coord), len(axes) + 1), + coord._as_defn(), + cube.coord_dims(coord)) for coord in sorted(cube.aux_coords, key=key_func): dims = cube.coord_dims(coord) @@ -647,8 +648,7 @@ def concatenate(self): # Sequence the skeleton segments into the correct order # pending concatenation. - key_func = lambda skeleton: skeleton.signature.dim_extents - skeletons.sort(key=key_func, + skeletons.sort(key=lambda skeleton: skeleton.signature.dim_extents, reverse=(order == _DECREASING)) # Concatenate the new dimension coordinate. diff --git a/lib/iris/_constraints.py b/lib/iris/_constraints.py index 9e3ee2426f..eb255f328b 100644 --- a/lib/iris/_constraints.py +++ b/lib/iris/_constraints.py @@ -264,11 +264,15 @@ def extract(self, cube): desired_values = list(self._coord_thing) # A dramatic speedup can be had if we don't have bounds. if coord.has_bounds(): - call_func = lambda cell: cell in desired_values + def call_func(cell): + return cell in desired_values else: - call_func = lambda cell: cell.point in desired_values + def call_func(cell): + return cell.point in desired_values else: - call_func = lambda c: c == self._coord_thing + def call_func(c): + return c == self._coord_thing + try_quick = (isinstance(coord, iris.coords.DimCoord) and not isinstance(self._coord_thing, iris.coords.Cell)) diff --git a/lib/iris/analysis/__init__.py b/lib/iris/analysis/__init__.py index 46618abf16..8bc74d37ba 100644 --- a/lib/iris/analysis/__init__.py +++ b/lib/iris/analysis/__init__.py @@ -283,39 +283,50 @@ def coord_comparison(*cubes): # Get all coordinate groups which aren't complete (i.e. there is a # None in the group) - coord_is_None_fn = lambda cube, coord: coord is None + def coord_is_None_fn(cube, coord): + return coord is None + if coord_group.matches_any(coord_is_None_fn): ungroupable.add(coord_group) # Get all coordinate groups which don't all equal one another # (None -> group not all equal) - not_equal_fn = lambda cube, coord: coord != first_coord + def not_equal_fn(cube, coord): + return coord != first_coord + if coord_group.matches_any(not_equal_fn): not_equal.add(coord_group) # Get all coordinate groups which don't all share the same shape # (None -> group has different shapes) - diff_shape_fn = lambda cube, coord: coord.shape != first_coord.shape + def diff_shape_fn(cube, coord): + return coord.shape != first_coord.shape + if coord_group.matches_any(diff_shape_fn): different_shaped_coords.add(coord_group) # Get all coordinate groups which don't all share the same data # dimension on their respective cubes # (None -> group describes a different dimension) - diff_data_dim_fn = lambda cube, coord: \ - cube.coord_dims(coord) != first_cube.coord_dims(first_coord) + def diff_data_dim_fn(cube, coord): + return cube.coord_dims(coord) != first_cube.coord_dims(first_coord) + if coord_group.matches_any(diff_data_dim_fn): different_data_dimension.add(coord_group) # get all coordinate groups which don't describe a dimension # (None -> doesn't describe a dimension) - no_data_dim_fn = lambda cube, coord: cube.coord_dims(coord) == () + def no_data_dim_fn(cube, coord): + return cube.coord_dims(coord) == () + if coord_group.matches_all(no_data_dim_fn): no_data_dimension.add(coord_group) # get all coordinate groups which don't describe a dimension # (None -> not a scalar coordinate) - no_data_dim_fn = lambda cube, coord: coord.shape == (1, ) + def no_data_dim_fn(cube, coord): + return coord.shape == (1, ) + if coord_group.matches_all(no_data_dim_fn): scalar_coords.add(coord_group) diff --git a/lib/iris/analysis/_interpolation.py b/lib/iris/analysis/_interpolation.py index d9ab6e6846..6266f8be6d 100644 --- a/lib/iris/analysis/_interpolation.py +++ b/lib/iris/analysis/_interpolation.py @@ -405,8 +405,8 @@ def _setup(self): # Only DimCoords can be circular. if circular: coord_points = extend_circular_coord(coord, coord_points) - offset = ((coord_points.max() + coord_points.min() - modulus) - * 0.5) + offset = 0.5 * (coord_points.max() + coord_points.min() - + modulus) self._circulars.append((circular, modulus, index, coord_dims[0], offset)) @@ -634,8 +634,8 @@ def construct_new_coord(coord): return new_coord, dims def gen_new_cube(): - if (isinstance(new_coord, DimCoord) and len(dims) > 0 - and dims[0] not in dims_with_dim_coords): + if (isinstance(new_coord, DimCoord) and len(dims) > 0 and + dims[0] not in dims_with_dim_coords): new_cube._add_unique_dim_coord(new_coord, dims) dims_with_dim_coords.append(dims[0]) else: diff --git a/lib/iris/coord_categorisation.py b/lib/iris/coord_categorisation.py index 189177946a..0c6aadd3f7 100644 --- a/lib/iris/coord_categorisation.py +++ b/lib/iris/coord_categorisation.py @@ -81,8 +81,10 @@ def add_categorised_coord(cube, name, from_coord, category_function, str_vectorised_fn = np.vectorize(category_function, otypes=[object]) # Use a common type for string arrays (N.B. limited to 64 chars) all_cases_string_type = '|S64' if six.PY2 else '|U64' - vectorised_fn = lambda *args: str_vectorised_fn(*args).astype( - all_cases_string_type) + + def vectorised_fn(*args): + return str_vectorised_fn(*args).astype(all_cases_string_type) + else: vectorised_fn = np.vectorize(category_function) new_coord = iris.coords.AuxCoord(vectorised_fn(from_coord, diff --git a/lib/iris/coord_systems.py b/lib/iris/coord_systems.py index 66a93c5ad5..1d23225940 100644 --- a/lib/iris/coord_systems.py +++ b/lib/iris/coord_systems.py @@ -911,9 +911,9 @@ def __init__(self, latitude_of_projection_origin=0.0, self.ellipsoid = ellipsoid def __repr__(self): - return "LambertAzimuthalEqualArea(latitude_of_projection_origin={!r}, "\ - "longitude_of_projection_origin={!r}, false_easting={!r}, "\ - "false_northing={!r}, ellipsoid={!r})".format( + return ("LambertAzimuthalEqualArea(latitude_of_projection_origin={!r}," + " longitude_of_projection_origin={!r}, false_easting={!r}," + " false_northing={!r}, ellipsoid={!r})").format( self.latitude_of_projection_origin, self.longitude_of_projection_origin, self.false_easting, diff --git a/lib/iris/coords.py b/lib/iris/coords.py index 8a75550992..20d4058b6a 100644 --- a/lib/iris/coords.py +++ b/lib/iris/coords.py @@ -964,7 +964,8 @@ def collapsed(self, dims_to_collapse=None): if np.issubdtype(self.dtype, np.str): # Collapse the coordinate by serializing the points and # bounds as strings. - serialize = lambda x: '|'.join([str(i) for i in x.flatten()]) + def serialize(x): + return '|'.join([str(i) for i in x.flatten()]) bounds = None string_type_fmt = 'S{}' if six.PY2 else 'U{}' if self.bounds is not None: diff --git a/lib/iris/cube.py b/lib/iris/cube.py index 3ac2546362..aa234ea71d 100644 --- a/lib/iris/cube.py +++ b/lib/iris/cube.py @@ -600,8 +600,8 @@ def _is_single_item(testee): We count string types as 'single', also. """ - return (isinstance(testee, six.string_types) - or not isinstance(testee, collections.Iterable)) + return (isinstance(testee, six.string_types) or + not isinstance(testee, collections.Iterable)) class Cube(CFVariableMixin): @@ -1132,7 +1132,8 @@ def coord_dims(self, coord): # Search derived aux coords target_defn = coord._as_defn() if not matches: - match = lambda factory: factory._as_defn() == target_defn + def match(factory): + return factory._as_defn() == target_defn factories = filter(match, self._aux_factories) matches = [factory.derived_dims(self.coord_dims) for factory in factories] @@ -1341,9 +1342,11 @@ def coords(self, name_or_coord=None, standard_name=None, msg = 'The attributes keyword was expecting a dictionary ' \ 'type, but got a %s instead.' % type(attributes) raise ValueError(msg) - attr_filter = lambda coord_: all(k in coord_.attributes and - coord_.attributes[k] == v for - k, v in six.iteritems(attributes)) + + def attr_filter(coord_): + return all(k in coord_.attributes and coord_.attributes[k] == v + for k, v in six.iteritems(attributes)) + coords_and_factories = [coord_ for coord_ in coords_and_factories if attr_filter(coord_)] @@ -2157,13 +2160,16 @@ def __getitem__(self, keys): # multiple times) dimension_mapping, slice_gen = iris.util.column_slices_generator( full_slice, len(self.shape)) - new_coord_dims = lambda coord_: [dimension_mapping[d] for d in - self.coord_dims(coord_) if - dimension_mapping[d] is not None] - new_cell_measure_dims = lambda cm_: [dimension_mapping[d] for d in - self.cell_measure_dims(cm_) if - dimension_mapping[d] is not None] + def new_coord_dims(coord_): + return [dimension_mapping[d] + for d in self.coord_dims(coord_) + if dimension_mapping[d] is not None] + + def new_cell_measure_dims(cm_): + return [dimension_mapping[d] + for d in self.cell_measure_dims(cm_) + if dimension_mapping[d] is not None] try: first_slice = next(slice_gen) @@ -2648,9 +2654,9 @@ def _as_list_of_coords(self, names_or_coords): coords.append(self.coord(name_or_coord)) else: # Don't know how to handle this type - msg = "Don't know how to handle coordinate of type %s. " \ - "Ensure all coordinates are of type six.string_types or " \ - "iris.coords.Coord." % type(name_or_coord) + msg = ("Don't know how to handle coordinate of type %s. " + "Ensure all coordinates are of type six.string_types " + "or iris.coords.Coord.") % (type(name_or_coord), ) raise TypeError(msg) return coords @@ -3316,8 +3322,8 @@ def collapsed(self, coords, aggregator, **kwargs): data_result = unrolled_data # Perform the aggregation in lazy form if possible. - elif (aggregator.lazy_func is not None - and len(dims_to_collapse) == 1 and self.has_lazy_data()): + elif (aggregator.lazy_func is not None and + len(dims_to_collapse) == 1 and self.has_lazy_data()): # Use a lazy operation separately defined by the aggregator, based # on the cube lazy array. # NOTE: do not reform the data in this case, as 'lazy_aggregate' diff --git a/lib/iris/experimental/equalise_cubes.py b/lib/iris/experimental/equalise_cubes.py index bf3379db66..8a85cded97 100644 --- a/lib/iris/experimental/equalise_cubes.py +++ b/lib/iris/experimental/equalise_cubes.py @@ -1,4 +1,4 @@ -# (C) British Crown Copyright 2013 - 2015, Met Office +# (C) British Crown Copyright 2013 - 2016, Met Office # # This file is part of Iris. # @@ -45,8 +45,8 @@ def equalise_attributes(cubes): cube_keys = list(cube.attributes.keys()) common_keys = [ key for key in common_keys - if key in cube_keys - and np.all(cube.attributes[key] == cubes[0].attributes[key])] + if (key in cube_keys and + np.all(cube.attributes[key] == cubes[0].attributes[key]))] # Remove all the other attributes. for cube in cubes: diff --git a/lib/iris/experimental/fieldsfile.py b/lib/iris/experimental/fieldsfile.py index f8cefe0669..9489277d1f 100644 --- a/lib/iris/experimental/fieldsfile.py +++ b/lib/iris/experimental/fieldsfile.py @@ -159,7 +159,8 @@ def adjust(dims): def _bind_coords(coords_and_dims, dim_coord_dims, dim_coords_and_dims, aux_coords_and_dims): - key_func = lambda item: _HINTS.get(item[0].name(), len(_HINTS)) + def key_func(item): + return _HINTS.get(item[0].name(), len(_HINTS)) # Target the first DimCoord for a dimension at dim_coords, # and target everything else at aux_coords. for coord, dims in sorted(coords_and_dims, key=key_func): diff --git a/lib/iris/fileformats/grib/_load_convert.py b/lib/iris/fileformats/grib/_load_convert.py index 1061d62da8..54a3cbcd38 100644 --- a/lib/iris/fileformats/grib/_load_convert.py +++ b/lib/iris/fileformats/grib/_load_convert.py @@ -152,7 +152,9 @@ def unscale(value, factor): is returned. """ - _unscale = lambda v, f: v / 10.0 ** f + def _unscale(v, f): + return v / 10.0 ** f + if isinstance(value, Iterable) or isinstance(factor, Iterable): def _masker(item): result = ma.masked_equal(item, _MDI) @@ -1072,15 +1074,15 @@ def grid_definition_template_90(section, metadata): raise TranslationError('Unsupported space-view orientation.') # Determine the coordinate system. - sub_satellite_lat = (section['latitudeOfSubSatellitePoint'] - * _GRID_ACCURACY_IN_DEGREES) + sub_satellite_lat = (section['latitudeOfSubSatellitePoint'] * + _GRID_ACCURACY_IN_DEGREES) # The subsequent calculations to determine the apparent Earth # diameters rely on the satellite being over the equator. if sub_satellite_lat != 0: raise TranslationError('Unsupported non-zero latitude for ' 'space-view perspective.') - sub_satellite_lon = (section['longitudeOfSubSatellitePoint'] - * _GRID_ACCURACY_IN_DEGREES) + sub_satellite_lon = (section['longitudeOfSubSatellitePoint'] * + _GRID_ACCURACY_IN_DEGREES) major, minor, radius = ellipsoid_geometry(section) geog_cs = ellipsoid(section['shapeOfTheEarth'], major, minor, radius) height_above_centre = geog_cs.semi_major_axis * section['Nr'] / 1e6 diff --git a/lib/iris/fileformats/netcdf.py b/lib/iris/fileformats/netcdf.py index 8e3d644633..f67d70bd61 100644 --- a/lib/iris/fileformats/netcdf.py +++ b/lib/iris/fileformats/netcdf.py @@ -525,7 +525,9 @@ def _load_cube(engine, cf, cf_var, filename): # Populate coordinate attributes with the untouched attributes from the # associated CF-netCDF variable. coordinates = engine.provides.get('coordinates', []) - attribute_predicate = lambda item: item[0] not in _CF_ATTRS + + def attribute_predicate(item): + return item[0] not in _CF_ATTRS for coord, cf_var_name in coordinates: tmpvar = filter(attribute_predicate, @@ -1836,9 +1838,9 @@ def _create_cf_data_variable(self, cube, dimension_names, local_keys=None, cf_name = self._increment_name(cf_name) # if netcdf3 avoid streaming due to dtype handling - if (not cube.has_lazy_data() - or self._dataset.file_format in ('NETCDF3_CLASSIC', - 'NETCDF3_64BIT')): + if (not cube.has_lazy_data() or + self._dataset.file_format in ('NETCDF3_CLASSIC', + 'NETCDF3_64BIT')): # Determine whether there is a cube MDI value. fill_value = None if isinstance(cube.data, ma.core.MaskedArray): diff --git a/lib/iris/fileformats/nimrod_load_rules.py b/lib/iris/fileformats/nimrod_load_rules.py index a5dc2922f0..66af00e8a5 100644 --- a/lib/iris/fileformats/nimrod_load_rules.py +++ b/lib/iris/fileformats/nimrod_load_rules.py @@ -1,4 +1,4 @@ -# (C) British Crown Copyright 2010 - 2015, Met Office +# (C) British Crown Copyright 2010 - 2016, Met Office # # This file is part of Iris. # @@ -156,10 +156,10 @@ def british_national_grid_y(cube, field): """ if field.origin_corner == 0: # top left - y_coord = DimCoord(np.arange(field.num_rows)[::-1] * - -field.row_step + field.y_origin, - standard_name="projection_y_coordinate", units="m", - coord_system=iris.coord_systems.OSGB()) + y_coord = DimCoord( + np.arange(field.num_rows)[::-1] * -field.row_step + field.y_origin, + standard_name="projection_y_coordinate", units="m", + coord_system=iris.coord_systems.OSGB()) cube.add_dim_coord(y_coord, 0) else: raise TranslationError("Corner {0} not yet implemented". diff --git a/lib/iris/fileformats/pp.py b/lib/iris/fileformats/pp.py index 26a00ab2f5..c5aeb75863 100644 --- a/lib/iris/fileformats/pp.py +++ b/lib/iris/fileformats/pp.py @@ -1411,8 +1411,8 @@ def save(self, file_handle): header_elem = int(header_elem) lb[index] = header_elem else: - index = slice(pos[0] - NUM_LONG_HEADERS, pos[-1] - - NUM_LONG_HEADERS + 1) + index = slice(pos[0] - NUM_LONG_HEADERS, + pos[-1] - NUM_LONG_HEADERS + 1) b[index] = header_elem # Although all of the elements are now populated, we still need to diff --git a/lib/iris/fileformats/um/_fast_load_structured_fields.py b/lib/iris/fileformats/um/_fast_load_structured_fields.py index 2ca79bcd6e..214931885f 100644 --- a/lib/iris/fileformats/um/_fast_load_structured_fields.py +++ b/lib/iris/fileformats/um/_fast_load_structured_fields.py @@ -120,10 +120,13 @@ def _field_vector_element_arrays(self): """Define the field components used in the structure analysis.""" # Define functions to make t1 and t2 values as date-time tuples. # These depend on header version (PPField2 has no seconds values). - t1_fn = lambda fld: (fld.lbyr, fld.lbmon, fld.lbdat, - fld.lbhr, fld.lbmin, getattr(fld, 'lbsec', 0)) - t2_fn = lambda fld: (fld.lbyrd, fld.lbmond, fld.lbdatd, - fld.lbhrd, fld.lbmind, getattr(fld, 'lbsecd', 0)) + def t1_fn(fld): + return (fld.lbyr, fld.lbmon, fld.lbdat, fld.lbhr, fld.lbmin, + getattr(fld, 'lbsec', 0)) + + def t2_fn(fld): + return (fld.lbyrd, fld.lbmond, fld.lbdatd, fld.lbhrd, fld.lbmind, + getattr(fld, 'lbsecd', 0)) # Return a list of (name, array) for the vectorizable elements. component_arrays = [ diff --git a/lib/iris/plot.py b/lib/iris/plot.py index 9aaba2eb7e..025e32ac42 100644 --- a/lib/iris/plot.py +++ b/lib/iris/plot.py @@ -167,8 +167,7 @@ def guess_axis(coord): aux_coords = [coord for coord in aux_coords if isinstance(coord, iris.coords.DimCoord)] if aux_coords: - key_func = lambda coord: coord._as_defn() - aux_coords.sort(key=key_func) + aux_coords.sort(key=lambda coord: coord._as_defn()) coords[dim] = aux_coords[0] if mode == iris.coords.POINT_MODE: @@ -974,7 +973,9 @@ def points(cube, *args, **kwargs): keyword arguments. """ - _scatter_args = lambda u, v, data, *args, **kwargs: ((u, v) + args, kwargs) + def _scatter_args(u, v, data, *args, **kwargs): + return ((u, v) + args, kwargs) + return _draw_2d_from_points('scatter', _scatter_args, cube, *args, **kwargs) diff --git a/lib/iris/tests/test_coding_standards.py b/lib/iris/tests/test_coding_standards.py index ec0c19aba5..c092aa285d 100644 --- a/lib/iris/tests/test_coding_standards.py +++ b/lib/iris/tests/test_coding_standards.py @@ -69,6 +69,13 @@ in exclusion] +# pycodestyle / pep8 error codes that should be ignored: +PYCODESTYLE_IGNORE_OPTIONS = ( + # "Module level import not at top of file" - due to conditional imports + 'E402', +) + + class StandardReportWithExclusions(pep8.StandardReport): expected_bad_files = [ '*/iris/std_names.py', @@ -180,6 +187,7 @@ def test_pep8_conformance(self): # "reporter=pep8.FileReport" to the StyleGuide constructor. pep8style = pep8.StyleGuide(quiet=False, reporter=StandardReportWithExclusions) + pep8style.options.ignore += PYCODESTYLE_IGNORE_OPTIONS # Allow users to add their own exclude list. extra_exclude_file = os.path.join(os.path.dirname(__file__), diff --git a/lib/iris/tests/test_grib_load_translations.py b/lib/iris/tests/test_grib_load_translations.py index f33f3078df..f868d8d70d 100644 --- a/lib/iris/tests/test_grib_load_translations.py +++ b/lib/iris/tests/test_grib_load_translations.py @@ -252,10 +252,8 @@ def _run_timetests(self, test_set): ) # Check the data-starttime calculation. - interval_start_to_end = ( - wrapped_msg._phenomenonDateTime - - wrapped_msg._referenceDateTime - ) + interval_start_to_end = (wrapped_msg._phenomenonDateTime - + wrapped_msg._referenceDateTime) if grib_edition == 1: interval_from_units = wrapped_msg.P1 else: diff --git a/lib/iris/tests/unit/analysis/cartography/test_rotate_winds.py b/lib/iris/tests/unit/analysis/cartography/test_rotate_winds.py index 617d919293..19ae497e48 100644 --- a/lib/iris/tests/unit/analysis/cartography/test_rotate_winds.py +++ b/lib/iris/tests/unit/analysis/cartography/test_rotate_winds.py @@ -1,4 +1,4 @@ -# (C) British Crown Copyright 2015, Met Office +# (C) British Crown Copyright 2015 - 2016, Met Office # # This file is part of Iris. # @@ -162,8 +162,8 @@ def _unrotate_equation(rotated_lons, rotated_lats, np.sin(np.radians(trueLongitude) - lambda_angle) * np.cos(phi_angle)) sin_rot = -((np.sin(np.radians(trueLongitude) - lambda_angle) * - np.sin(phi_angle)) - / np.cos(np.radians(rotated_lats))) + np.sin(phi_angle)) / + np.cos(np.radians(rotated_lats))) # Matrix-multiply to rotate the vectors. u_true = rotated_us * cos_rot - rotated_vs * sin_rot diff --git a/lib/iris/tests/unit/analysis/regrid/test_RectilinearRegridder.py b/lib/iris/tests/unit/analysis/regrid/test_RectilinearRegridder.py index 6b2aa23a41..a307603bad 100644 --- a/lib/iris/tests/unit/analysis/regrid/test_RectilinearRegridder.py +++ b/lib/iris/tests/unit/analysis/regrid/test_RectilinearRegridder.py @@ -46,10 +46,13 @@ def setUp(self): self.y = DimCoord(np.linspace(0, 49, 50)) self.xs, self.ys = np.meshgrid(self.x.points, self.y.points) - transformation = lambda x, y: x + y ** 2 + def transformation(x, y): + return x + y ** 2 + # Construct a function which adds dimensions to the 2D data array # so that we can test higher dimensional functionality. - dim_extender = lambda arr: (arr[np.newaxis, ..., np.newaxis] * [1, 2]) + def dim_extender(arr): + return arr[np.newaxis, ..., np.newaxis] * [1, 2] self.data = dim_extender(transformation(self.xs, self.ys)) diff --git a/lib/iris/tests/unit/coord_categorisation/test_add_categorised_coord.py b/lib/iris/tests/unit/coord_categorisation/test_add_categorised_coord.py index 3d78b06fb8..de21b9a0eb 100644 --- a/lib/iris/tests/unit/coord_categorisation/test_add_categorised_coord.py +++ b/lib/iris/tests/unit/coord_categorisation/test_add_categorised_coord.py @@ -1,4 +1,4 @@ -# (C) British Crown Copyright 2013 - 2015, Met Office +# (C) British Crown Copyright 2013 - 2016, Met Office # # This file is part of Iris. # @@ -49,7 +49,8 @@ def test_vectorise_call(self): # numpy.vectorize, before being applied to the points array. # The reason we use numpy.vectorize is to support multi-dimensional # coordinate points. - fn = lambda coord, v: v**2 + def fn(coord, v): + return v**2 with mock.patch('numpy.vectorize', return_value=self.vectorised) as vectorise_patch: @@ -75,7 +76,8 @@ def test_vectorise_call(self): def test_string_vectorised(self): # Check that special case handling of a vectorized string returning # function is taking place. - fn = lambda coord, v: '0123456789'[:v] + def fn(coord, v): + return '0123456789'[:v] with mock.patch('numpy.vectorize', return_value=self.vectorised) as vectorise_patch: diff --git a/lib/iris/tests/unit/cube/test_Cube.py b/lib/iris/tests/unit/cube/test_Cube.py index f68214e4f2..4b51bc53b0 100644 --- a/lib/iris/tests/unit/cube/test_Cube.py +++ b/lib/iris/tests/unit/cube/test_Cube.py @@ -327,8 +327,7 @@ def setUp(self): self.mock_agg.aggregate = mock.Mock( return_value=mock.Mock(dtype='object')) self.mock_agg.aggregate_shape = mock.Mock(return_value=()) - post_process_func = lambda x, y, z: x - self.mock_agg.post_process = mock.Mock(side_effect=post_process_func) + self.mock_agg.post_process = mock.Mock(side_effect=lambda x, y, z: x) def test_string_coord_agg_by_label(self): # Aggregate a cube on a string coordinate label where label @@ -379,8 +378,7 @@ def setUp(self): self.mock_agg = mock.Mock(spec=Aggregator) self.mock_agg.aggregate = mock.Mock( return_value=np.empty([4])) - post_process_func = lambda x, y, z: x - self.mock_agg.post_process = mock.Mock(side_effect=post_process_func) + self.mock_agg.post_process = mock.Mock(side_effect=lambda x, y, z: x) def test_string_coord(self): # Rolling window on a cube that contains a string coordinate. diff --git a/lib/iris/tests/unit/fileformats/grib/load_convert/test_convert.py b/lib/iris/tests/unit/fileformats/grib/load_convert/test_convert.py index b93e185262..2ab05af4f4 100644 --- a/lib/iris/tests/unit/fileformats/grib/load_convert/test_convert.py +++ b/lib/iris/tests/unit/fileformats/grib/load_convert/test_convert.py @@ -1,4 +1,4 @@ -# (C) British Crown Copyright 2014 - 2015, Met Office +# (C) British Crown Copyright 2014 - 2016, Met Office # # This file is part of Iris. # @@ -35,7 +35,10 @@ def test_call(self): field = _make_test_message(sections) this = 'iris.fileformats.grib._load_convert.grib2_convert' factory = mock.sentinel.factory - func = lambda field, metadata: metadata['factories'].append(factory) + + def func(field, metadata): + return metadata['factories'].append(factory) + with mock.patch(this, side_effect=func) as grib2_convert: # The call being tested. result = convert(field) diff --git a/lib/iris/tests/unit/fileformats/grib/load_convert/test_grid_definition_template_5.py b/lib/iris/tests/unit/fileformats/grib/load_convert/test_grid_definition_template_5.py index 5fb8b53784..e799bf4d72 100644 --- a/lib/iris/tests/unit/fileformats/grib/load_convert/test_grid_definition_template_5.py +++ b/lib/iris/tests/unit/fileformats/grib/load_convert/test_grid_definition_template_5.py @@ -1,4 +1,4 @@ -# (C) British Crown Copyright 2014 - 2015, Met Office +# (C) British Crown Copyright 2014 - 2016, Met Office # # This file is part of Iris. # @@ -50,8 +50,11 @@ def setUp(self): self.coord = mock.sentinel.coord self.dim = mock.sentinel.dim item = (self.coord, self.dim) - func = lambda s, m, y, x, c: m['dim_coords_and_dims'].append(item) + + def func(s, m, y, x, c): + return m['dim_coords_and_dims'].append(item) patch.append(mock.patch(this, side_effect=func)) + this = 'iris.coord_systems.RotatedGeogCS' self.cs = mock.sentinel.cs patch.append(mock.patch(this, return_value=self.cs)) diff --git a/lib/iris/tests/unit/fileformats/grib/load_convert/test_product_definition_template_1.py b/lib/iris/tests/unit/fileformats/grib/load_convert/test_product_definition_template_1.py index 47a832e9a9..d8c8f5344e 100644 --- a/lib/iris/tests/unit/fileformats/grib/load_convert/test_product_definition_template_1.py +++ b/lib/iris/tests/unit/fileformats/grib/load_convert/test_product_definition_template_1.py @@ -1,4 +1,4 @@ -# (C) British Crown Copyright 2014 - 2015, Met Office +# (C) British Crown Copyright 2014 - 2016, Met Office # # This file is part of Iris. # @@ -41,8 +41,11 @@ def setUp(self): self.patch('warnings.warn') this = '{}.product_definition_template_0'.format(module) self.cell_method = mock.sentinel.cell_method - func = lambda s, m, f: m['cell_methods'].append(self.cell_method) + + def func(s, m, f): + return m['cell_methods'].append(self.cell_method) self.patch(this, side_effect=func) + self.metadata = {'factories': [], 'references': [], 'standard_name': None, 'long_name': None, 'units': None, 'attributes': {}, diff --git a/lib/iris/tests/unit/fileformats/grib/load_convert/test_product_definition_template_11.py b/lib/iris/tests/unit/fileformats/grib/load_convert/test_product_definition_template_11.py index e2e3457d77..a20cb4cf75 100644 --- a/lib/iris/tests/unit/fileformats/grib/load_convert/test_product_definition_template_11.py +++ b/lib/iris/tests/unit/fileformats/grib/load_convert/test_product_definition_template_11.py @@ -41,8 +41,11 @@ def setUp(self): self.patch('warnings.warn') this_module = '{}.product_definition_template_11'.format(module) self.cell_method = mock.sentinel.cell_method - func = lambda s, m, f: m['cell_methods'].append(self.cell_method) + + def func(s, m, f): + return m['cell_methods'].append(self.cell_method) self.patch(this_module, side_effect=func) + self.patch_statistical_fp_coord = self.patch( module + '.statistical_forecast_period_coord', return_value=mock.sentinel.dummy_fp_coord) diff --git a/lib/iris/tests/unit/fileformats/grib/load_convert/test_product_definition_template_31.py b/lib/iris/tests/unit/fileformats/grib/load_convert/test_product_definition_template_31.py index b06fa7145b..59f6f327f8 100644 --- a/lib/iris/tests/unit/fileformats/grib/load_convert/test_product_definition_template_31.py +++ b/lib/iris/tests/unit/fileformats/grib/load_convert/test_product_definition_template_31.py @@ -1,4 +1,4 @@ -# (C) British Crown Copyright 2014 - 2015, Met Office +# (C) British Crown Copyright 2014 - 2016, Met Office # # This file is part of Iris. # @@ -64,7 +64,11 @@ def _check(self, request_warning=False, value=10, factor=1): with mock.patch(this, warn_on_unsupported=request_warning): # The call being tested. product_definition_template_31(section, metadata, rt_coord) + # Check the result. + def unscale(v, f): + return v / 10.0 ** f + expected = deepcopy(self.metadata) coord = AuxCoord(series, long_name='satellite_series') expected['aux_coords_and_dims'].append((coord, None)) @@ -72,7 +76,6 @@ def _check(self, request_warning=False, value=10, factor=1): expected['aux_coords_and_dims'].append((coord, None)) coord = AuxCoord(instrument, long_name='instrument_type') expected['aux_coords_and_dims'].append((coord, None)) - unscale = lambda v, f: v / 10.0 ** f standard_name = 'sensor_band_central_radiation_wavenumber' coord = AuxCoord(unscale(value, factor), standard_name=standard_name, diff --git a/lib/iris/tests/unit/fileformats/grib/load_convert/test_vertical_coords.py b/lib/iris/tests/unit/fileformats/grib/load_convert/test_vertical_coords.py index 5775502b98..51f5c68407 100644 --- a/lib/iris/tests/unit/fileformats/grib/load_convert/test_vertical_coords.py +++ b/lib/iris/tests/unit/fileformats/grib/load_convert/test_vertical_coords.py @@ -1,4 +1,4 @@ -# (C) British Crown Copyright 2014 - 2015, Met Office +# (C) British Crown Copyright 2014 - 2016, Met Office # # This file is part of Iris. # @@ -50,7 +50,10 @@ def test_hybrid_factories(self): section = {'NV': 1} this = 'iris.fileformats.grib._load_convert.hybrid_factories' factory = mock.sentinel.factory - func = lambda section, metadata: metadata['factories'].append(factory) + + def func(section, metadata): + return metadata['factories'].append(factory) + with mock.patch(this, side_effect=func) as hybrid_factories: vertical_coords(section, metadata) self.assertTrue(hybrid_factories.called) diff --git a/lib/iris/tests/unit/fileformats/pyke_rules/compiled_krb/fc_rules_cf_fc/test_reorder_bounds_data.py b/lib/iris/tests/unit/fileformats/pyke_rules/compiled_krb/fc_rules_cf_fc/test_reorder_bounds_data.py index cb0786af88..4c8b562dc6 100644 --- a/lib/iris/tests/unit/fileformats/pyke_rules/compiled_krb/fc_rules_cf_fc/test_reorder_bounds_data.py +++ b/lib/iris/tests/unit/fileformats/pyke_rules/compiled_krb/fc_rules_cf_fc/test_reorder_bounds_data.py @@ -1,4 +1,4 @@ -# (C) British Crown Copyright 2014 - 2015, Met Office +# (C) British Crown Copyright 2014 - 2016, Met Office # # This file is part of Iris. # @@ -58,8 +58,7 @@ def test_slowest_varying(self): def test_slowest_varying_lazy(self): bounds_data = np.arange(24).reshape(4, 2, 3) - func = lambda: bounds_data - lazy_bounds_data = _LazyArray(bounds_data.shape, func, + lazy_bounds_data = _LazyArray(bounds_data.shape, lambda: bounds_data, bounds_data.dtype) cf_bounds_var = mock.Mock(dimensions=('nv', 'foo', 'bar')) cf_coord_var = mock.Mock(dimensions=('foo', 'bar')) diff --git a/lib/iris/tests/unit/fileformats/test_rules.py b/lib/iris/tests/unit/fileformats/test_rules.py index a41d1b48a7..b815b0fece 100644 --- a/lib/iris/tests/unit/fileformats/test_rules.py +++ b/lib/iris/tests/unit/fileformats/test_rules.py @@ -52,7 +52,9 @@ def test_attributes(self): self.assertEqual(target.name, 'foo') self.assertIsNone(target.transform) - transform = lambda _: _ + def transform(_): + return _ + target = ConcreteReferenceTarget('foo', transform) self.assertEqual(target.name, 'foo') self.assertIs(target.transform, transform) @@ -64,7 +66,9 @@ def test_single_cube_no_transform(self): self.assertIs(target.as_cube(), src) def test_single_cube_with_transform(self): - transform = lambda cube: {'long_name': 'wibble'} + def transform(cube): + return {'long_name': 'wibble'} + target = ConcreteReferenceTarget('foo', transform) src = stock.simple_2d() target.add_cube(src) @@ -84,7 +88,9 @@ def test_multiple_cubes_no_transform(self): self.assertEqual(dest, src) def test_multiple_cubes_with_transform(self): - transform = lambda cube: {'long_name': 'wibble'} + def transform(cube): + return {'long_name': 'wibble'} + target = ConcreteReferenceTarget('foo', transform) src = stock.realistic_4d() for i in range(src.shape[0]): @@ -104,7 +110,10 @@ def test_simple_factory(self): # The fake PPField which will be supplied to our converter. field = Mock() field.data = None - field_generator = lambda filename: [field] + + def field_generator(filename): + return [field] + # A fake conversion function returning: # 1) A parameter cube needing a simple factory construction. aux_factory = Mock() @@ -167,7 +176,10 @@ def test_cross_reference(self): press_field.data = param_cube.data orog_field = Mock() orog_field.data = orog_cube.data - field_generator = lambda filename: [press_field, orog_field] + + def field_generator(filename): + return [press_field, orog_field] + # A fake rule set returning: # 1) A parameter cube needing an "orography" reference # 2) An "orography" cube diff --git a/lib/iris/unit.py b/lib/iris/unit.py index 81f83c4321..7ccc251af0 100644 --- a/lib/iris/unit.py +++ b/lib/iris/unit.py @@ -1871,8 +1871,7 @@ def convert(self, value, other, ctype=FLOAT64): ut2 = other.utime() result = ut2.date2num(ut1.num2date(value_copy)) # Preserve the datatype of the input array if it was float32. - if (isinstance(value, np.ndarray) - and value.dtype == np.float32): + if isinstance(value, np.ndarray) and value.dtype == np.float32: result = result.astype(np.float32) else: ut_converter = _ut_get_converter(self.ut_unit, other.ut_unit) diff --git a/lib/iris/util.py b/lib/iris/util.py index e85b658912..ebb6bfa746 100644 --- a/lib/iris/util.py +++ b/lib/iris/util.py @@ -306,8 +306,8 @@ def guess_coord_axis(coord): elif coord.standard_name in ('latitude', 'grid_latitude', 'projection_y_coordinate'): axis = 'Y' - elif (coord.units.is_convertible('hPa') - or coord.attributes.get('positive') in ('up', 'down')): + elif (coord.units.is_convertible('hPa') or + coord.attributes.get('positive') in ('up', 'down')): axis = 'Z' elif coord.units.is_time_reference(): axis = 'T' @@ -598,8 +598,9 @@ def column_slices_generator(full_slice, ndims): # Get all of the dimensions for which a tuple of indices were provided # (numpy.ndarrays are treated in the same way tuples in this case) - is_tuple_style_index = lambda key: isinstance(key, tuple) or \ - (isinstance(key, np.ndarray) and key.ndim == 1) + def is_tuple_style_index(key): + return (isinstance(key, tuple) or + (isinstance(key, np.ndarray) and key.ndim == 1)) tuple_indices = [i for i, key in enumerate(full_slice) if is_tuple_style_index(key)] diff --git a/minimal-conda-requirements.txt b/minimal-conda-requirements.txt index 5aef25c0f8..bf517e5f19 100644 --- a/minimal-conda-requirements.txt +++ b/minimal-conda-requirements.txt @@ -17,7 +17,7 @@ setuptools # Iris testing/documentation dependencies mock nose -pep8=1.5.7 +pep8 sphinx filelock