From 91aea062c75d5df947d5b1e0c25dacb48696d724 Mon Sep 17 00:00:00 2001 From: Benjamin Adams Date: Mon, 16 Sep 2024 11:54:27 -0400 Subject: [PATCH 1/2] Simplify tuple destructuring in output routine --- compliance_checker/runner.py | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/compliance_checker/runner.py b/compliance_checker/runner.py index 536888f5..ffbdeaa1 100644 --- a/compliance_checker/runner.py +++ b/compliance_checker/runner.py @@ -148,22 +148,12 @@ def stdout_output(cls, cs, score_dict, verbose, limit): """ for ds, score_groups in score_dict.items(): - for checker, rpair in score_groups.items(): - groups, errors = rpair + for checker, (groups, errors) in score_groups.items(): score_list, points, out_of = cs.standard_output( - ds, - limit, - checker, - groups, - ) + ds, limit, checker, groups) # send list of grouped result objects to stdout & reasoning_routine cs.standard_output_generation( - groups, - limit, - points, - out_of, - check=checker, - ) + groups, limit, points, out_of, check=checker) return groups @classmethod From a234b4c04becc4d3e4772d6d90375345b703c5d8 Mon Sep 17 00:00:00 2001 From: Benjamin Adams Date: Fri, 6 Dec 2024 12:28:44 -0500 Subject: [PATCH 2/2] Group search traversal routines --- compliance_checker/cf/util.py | 59 ++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/compliance_checker/cf/util.py b/compliance_checker/cf/util.py index 67cba708..a2150f25 100644 --- a/compliance_checker/cf/util.py +++ b/compliance_checker/cf/util.py @@ -4,10 +4,15 @@ from importlib.resources import files from pkgutil import get_data +from functools import lru_cache import requests from cf_units import Unit from lxml import etree -from netCDF4 import Dataset +from netCDF4 import Variable, Dimension, Dataset, Group + +import posixpath + +from typing import Tuple, Union from compliance_checker.cfutil import units_convertible @@ -405,6 +410,58 @@ def string_from_var_type(variable): ) +def get_possible_label_variable_dimensions(variable: Variable) -> Tuple[int, ...]: + """ + Return dimensions if non-char variable, or return variable dimensions + without trailing dimension if char variable, treating it as a label variable. + """ + if variable.kind == "C" and len(variable.dimensions) > 0: + return variable.dimensions[:-1] + return variable.dimensions + + +@lru_cache() +def maybe_lateral_reference_variable_or_dimension(group: Union[Group, Dataset], + name: str, + reference_type: Union[Variable, Dimension]): + + def can_lateral_search(name): + return (not name.startswith(".") and posixpath.split(name)[0] == "") + + if reference_type == "variable": + # first try to fetch any + # can't set to None with .get + try: + maybe_var = group[name] + except IndexError: + maybe_var = None + else: + if isinstance(maybe_var, Variable): + return maybe_var + + # alphanumeric string by itself, not a relative or absolute + # search by proximity + if (posixpath.split(name)[0] == "" and + not (name.startswith(".") or name.startswith("/"))): + group_traverse = group + while group_traverse.parent: + group_traverse = group_traverse.parent + check_target = posixpath.join(group_traverse.path, name) + try: + maybe_var = group_traverse[name] + except IndexError: + maybe_var = None + else: + if isinstance(maybe_var, Variable): + return maybe_var + else: + return VariableReferenceError(name) + + # can't find path relative to current group or absolute path + # perform lateral search if we aren't in the root group + + + def reference_attr_variables( dataset: Dataset, attributes_string: str,