Repository: ioos/compliance-checker

Issue:
CFBaseCheck::check_cell_measures() failing
Hi,

There are 2 small bugs in the CF suite (`check_cell_measure()` method), which eluded detection because corresponding [unit test](https://github.com/ioos/compliance-checker/blob/master/compliance_checker/tests/test_cf.py#L352) doesn't really test the right thing.

1. netcdf4's [get_variables_by_attributes](https://github.com/ioos/compliance-checker/blob/master/compliance_checker/cf/cf.py#L2579) returns a list of variables, not just their names, so they cannot be used for indexing of ds.variables

Something along these lines should fix it

```python
tested_vars = ds.get_variables_by_attributes(cell_measures=lambda c: c is not None)
for tested_var in tested_vars:
    var_name = tested_var.name
        var = ds.variables[var_name]
```
2. Also, a few lines below, `search_res.groups[0]` will fail because `groups` in `re.MatchObject` is a method, not an attribute (unlike in `re.RegexObject`)



Discussion:
Thanks for the catch, I have a PR in that should fix this and adds a unit test to check it.
I noticed a code issue when running the test script from #497 about variables used before they are assigned.  I've got the code fix, but the new tests fail, so I'm investigating/fixing those.  This is not quite finished.

Resolving patch:
diff --git a/compliance_checker/cf/cf.py b/compliance_checker/cf/cf.py
--- a/compliance_checker/cf/cf.py
+++ b/compliance_checker/cf/cf.py
@@ -2595,40 +2595,40 @@ def check_cell_measures(self, ds):
                                  "'volume: cell_var' where cell_var is the "
                                  "variable describing the cell measures".format(
                                      var.name))
-                continue
-            valid = True
-            cell_meas_var_name = search_res.groups()[0]
-            # TODO: cache previous results
-            if cell_meas_var_name not in ds.variables:
-                valid = False
-                reasoning.append(
-                    "Cell measure variable {} referred to by "
-                    "{} is not present in dataset variables".format(
-                        var.name, cell_meas_var_name)
-                )
             else:
-                cell_meas_var = ds.variables[cell_meas_var_name]
-                if not hasattr(cell_meas_var, 'units'):
-                    valid = False
-                    reasoning.append(
-                        "Cell measure variable {} is required "
-                        "to have units attribute defined.".format(
-                            cell_meas_var_name)
-                    )
-                if not set(cell_meas_var.dimensions).issubset(var.dimensions):
+                valid = True
+                cell_meas_var_name = search_res.groups()[0]
+                # TODO: cache previous results
+                if cell_meas_var_name not in ds.variables:
                     valid = False
                     reasoning.append(
-                        "Cell measure variable {} must have "
-                        "dimensions which are a subset of "
-                        "those defined in variable {}.".format(
-                            cell_meas_var_name, var.name)
+                        "Cell measure variable {} referred to by "
+                        "{} is not present in dataset variables".format(
+                            var.name, cell_meas_var_name)
                     )
+                else:
+                    cell_meas_var = ds.variables[cell_meas_var_name]
+                    if not hasattr(cell_meas_var, 'units'):
+                        valid = False
+                        reasoning.append(
+                            "Cell measure variable {} is required "
+                            "to have units attribute defined.".format(
+                                cell_meas_var_name)
+                        )
+                    if not set(cell_meas_var.dimensions).issubset(var.dimensions):
+                        valid = False
+                        reasoning.append(
+                            "Cell measure variable {} must have "
+                            "dimensions which are a subset of "
+                            "those defined in variable {}.".format(
+                                cell_meas_var_name, var.name)
+                        )
 
-        result = Result(BaseCheck.MEDIUM,
-                        valid,
-                        ('§7.2 Cell measures', var.name, 'cell_measures'),
-                        reasoning)
-        ret_val.append(result)
+            result = Result(BaseCheck.MEDIUM,
+                            valid,
+                            ('§7.2 Cell measures', var.name, 'cell_measures'),
+                            reasoning)
+            ret_val.append(result)
 
         return ret_val
 


Test patch: