Skip to content

Commit

Permalink
Avoid a crash if dataset has supplementary variables (#2198)
Browse files Browse the repository at this point in the history
Co-authored-by: Valeriu Predoi <[email protected]>
  • Loading branch information
bouweandela and valeriupredoi authored Sep 26, 2023
1 parent 60e0d2b commit a6f257a
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 0 deletions.
19 changes: 19 additions & 0 deletions esmvalcore/_recipe/from_datasets.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,23 @@ def _group_identical_facets(variable: Mapping[str, Any]) -> Recipe:
return result


class _SortableDict(dict):
"""A `dict` class that can be sorted."""

def __lt__(self, other):
return tuple(self.items()) < tuple(other.items())


def _change_dict_type(item, dict_type):
"""Change the dict type in a nested structure."""
change_dict_type = partial(_change_dict_type, dict_type=dict_type)
if isinstance(item, dict):
return dict_type((k, change_dict_type(v)) for k, v in item.items())
if isinstance(item, (list, tuple, set)):
return type(item)(change_dict_type(elem) for elem in item)
return item


def _group_ensemble_members(dataset_facets: Iterable[Facets]) -> list[Facets]:
"""Group ensemble members.
Expand All @@ -171,6 +188,7 @@ def grouper(facets):
return tuple((k, facets[k]) for k in sorted(facets) if k != 'ensemble')

result = []
dataset_facets = _change_dict_type(dataset_facets, _SortableDict)
dataset_facets = sorted(dataset_facets, key=grouper)
for group_facets, group in itertools.groupby(dataset_facets, key=grouper):
ensembles = [f['ensemble'] for f in group if 'ensemble' in f]
Expand All @@ -181,6 +199,7 @@ def grouper(facets):
facets = dict(group_facets)
facets['ensemble'] = ensemble
result.append(facets)
result = _change_dict_type(result, dict)
return result


Expand Down
7 changes: 7 additions & 0 deletions tests/unit/recipe/test_from_datasets.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
_group_ensemble_names,
_group_identical_facets,
_move_one_level_up,
_SortableDict,
_to_frozen,
datasets_to_recipe,
)
Expand Down Expand Up @@ -136,6 +137,12 @@ def test_supplementary_datasets_to_recipe():
assert datasets_to_recipe([dataset]) == recipe


def test_sortable_dict():
assert _SortableDict({'a': 1}) < _SortableDict({'a': 2})
assert _SortableDict({'a': 1}) < _SortableDict({'a': 1, 'b': 1})
assert _SortableDict({'a': 1}) < _SortableDict({'b': 1})


def test_datasets_to_recipe_group_ensembles():
datasets = [
Dataset(
Expand Down

0 comments on commit a6f257a

Please sign in to comment.