docs: def check_latitude(self, ds):
          '''
          Check variable(s) that define latitude and are defined correctly according to CF.
  
          CF §4.1 Variables representing latitude must always explicitly include
          the units attribute; there is no default value.  The recommended unit
          of latitude is degrees_north. Also acceptable are degree_north,
          degree_N, degrees_N, degreeN, and degreesN.
  
          Optionally, the latitude type may be indicated additionally by
          providing the standard_name attribute with the value latitude, and/or
          the axis attribute with the value Y.
  
          - Four checks per latitude variable
          - (H) latitude has units attribute
          - (M) latitude has an allowed units attribute
          - (L) latitude uses degrees_north (if not in rotated pole)
          - (M) latitude defines either standard_name or axis
  
          :param netCDF4.Dataset ds: An open netCDF dataset
          :rtype: list
          :return: List of results
          '''
          ret_val = []
  
          allowed_lat_units = [
              'degrees_north',
              'degree_north',
              'degree_n',
              'degrees_n',
              'degreen',
              'degreesn'
          ]
  
          # Determine the grid mappings in this dataset
          grid_mapping = []
          grid_mapping_variables = cfutil.get_grid_mapping_variables(ds)
          for name in grid_mapping_variables:
              variable = ds.variables[name]
              grid_mapping_name = getattr(variable, 'grid_mapping_name', None)
              if grid_mapping_name:
                  grid_mapping.append(grid_mapping_name)
  
          latitude_variables = cfutil.get_latitude_variables(ds)
          for latitude in latitude_variables:
              variable = ds.variables[latitude]
              units = getattr(variable, 'units', None)
              units_is_string = isinstance(units, basestring)
              standard_name = getattr(variable, 'standard_name', None)
              axis = getattr(variable, 'axis', None)
  
              # Check that latitude defines units
              valid_latitude = TestCtx(BaseCheck.HIGH, self.section_titles['4.1'])
              valid_latitude.assert_true(units is not None,
                                         "latitude variable '{}' must define units".format(latitude))
              ret_val.append(valid_latitude.to_result())
  
              # Check that latitude uses allowed units
              allowed_units = TestCtx(BaseCheck.MEDIUM, self.section_titles['4.1'])
              if standard_name == 'grid_latitude':
                  e_n_units = cfutil.VALID_LAT_UNITS | cfutil.VALID_LON_UNITS
                  # check that the units aren't in east and north degrees units,
                  # but are convertible to angular units
                  allowed_units.assert_true(units not in e_n_units and
                                            Unit(units) == Unit('degree'),
                                            "Grid latitude variable '{}' should use degree equivalent units without east or north components. "
                                            "Current units are {}".format(latitude, units))
              else:
                  allowed_units.assert_true(units_is_string and units.lower() in allowed_lat_units,
                                            "latitude variable '{}' should define valid units for latitude"
                                            "".format(latitude))
              ret_val.append(allowed_units.to_result())
  
              # Check that latitude uses degrees_north
              if standard_name == 'latitude' and units != 'degrees_north':
                  # This is only a recommendation and we won't penalize but we
                  # will include a recommended action.
                  msg = ("CF recommends latitude variable '{}' to use units degrees_north"
                         "".format(latitude))
                  recommended_units = Result(BaseCheck.LOW, (1, 1), self.section_titles['4.1'], [msg])
                  ret_val.append(recommended_units)
  
              y_variables = ds.get_variables_by_attributes(axis='Y')
              # Check that latitude defines either standard_name or axis
              definition = TestCtx(BaseCheck.MEDIUM, self.section_titles['4.1'])
              definition.assert_true(standard_name == 'latitude' or axis == 'Y' or y_variables != [],
                                     "latitude variable '{}' should define standard_name='latitude' or axis='Y'"
                                     "".format(latitude))
              ret_val.append(definition.to_result())
  
          return ret_val