Skip to content

Commit

Permalink
Merge pull request #1091 from sol1105/inputoptions
Browse files Browse the repository at this point in the history
Adding inputs (i.e. options incl. value)
  • Loading branch information
benjwadams authored Jul 15, 2024
2 parents dd0657a + f28f321 commit 8f96172
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 12 deletions.
23 changes: 14 additions & 9 deletions cchecker.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,25 @@ def _print_checker_name_header(checker_str):

def parse_options(opts):
"""
Helper function to parse possible options. Splits option after the first
colon to split into key/value pairs.
Helper function to parse possible options. Splits option into key/value
pairs and optionally a value for the checker option. The separator
is a colon.
:param opts: Iterable of strings with options
:rtype: dict
:return: Dictionary with keys as checker type (i.e. "cf", "acdd")
:return: Dictionary with keys as checker type (i.e. "cf", "acdd").
Each value is a dictionary where keys are checker options and values
are checker option values or None if not provided.
"""
options_dict = defaultdict(set)
options_dict = defaultdict(dict)
for opt_str in opts:
try:
checker_type, checker_opt = opt_str.split(":", 1)
checker_type, checker_opt, *checker_val = opt_str.split(":", 2)
checker_val = checker_val[0] if checker_val else None
except ValueError:
warnings.warn(f"Could not split option {opt_str}, ignoring", stacklevel=2)
else:
options_dict[checker_type].add(checker_opt)
options_dict[checker_type][checker_opt] = checker_val
return options_dict


Expand Down Expand Up @@ -174,8 +178,9 @@ def main():
checkers. Multiple options can be specified
via multiple invocations of this switch.
Options should be prefixed with a the
checker name followed by the option, e.g.
'<checker>:<option_name>'
checker name followed by the option,
potentially followed by a value, e.g.
'<checker>:<option_name>[:<option_value>]'
Available options:
'cf:enable_appendix_a_checks' - Allow check
Expand Down Expand Up @@ -235,7 +240,7 @@ def main():
print(f"IOOS compliance checker version {__version__}")
sys.exit(0)

options_dict = parse_options(args.option) if args.option else defaultdict(set)
options_dict = parse_options(args.option) if args.option else defaultdict(dict)

if args.describe_checks:
error_stat = 0
Expand Down
2 changes: 1 addition & 1 deletion compliance_checker/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ def setup(self, ds):
def __init__(self, options=None):
self._defined_results = defaultdict(lambda: defaultdict(dict))
if options is None:
self.options = set()
self.options = {}
else:
self.options = options

Expand Down
2 changes: 1 addition & 1 deletion compliance_checker/suite.py
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ def run_all(self, ds, checker_names, include_checks=None, skip_checks=None):
# use some kind of checker object with checker type and
# version baked in
checker_type_name = checker_name.split(":")[0]
checker_opts = self.options.get(checker_type_name, set())
checker_opts = self.options.get(checker_type_name, {})

# instantiate a Checker object
try:
Expand Down
2 changes: 1 addition & 1 deletion compliance_checker/tests/test_cf.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ def test_appendix_a(self):
dataset = self.load_dataset(STATIC_FILES["bad_data_type"])
# Ordinarily, options would be specified in the checker constructor, but
# we set them manually here so we don't have to monkey patch `setUp`
self.cf.options = {"enable_appendix_a_checks"}
self.cf.options = {"enable_appendix_a_checks": None}
new_check = copy.deepcopy(self.cf)
self.cf.setup(dataset)
aa_results = self.cf.check_appendix_a(dataset)
Expand Down
23 changes: 23 additions & 0 deletions compliance_checker/tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@
import json
import os
import platform
import shutil
import subprocess
import sys
from argparse import Namespace
from collections import defaultdict
from importlib.machinery import SourceFileLoader

import pytest

Expand Down Expand Up @@ -268,3 +271,23 @@ def test_nczarr_pass_through(self, zarr_url):
output_format="text",
)
assert not errors


def test_parse_options():
"""Test the option parser of cchecker.py"""
# Load cchecker.py
cchecker = SourceFileLoader("cchecker", shutil.which("cchecker.py")).load_module()
# Simple test checker_type:checker_opt
opt_dict = cchecker.parse_options(["cf:enable_appendix_a_checks"])
assert opt_dict == defaultdict(dict, {"cf": {"enable_appendix_a_checks": None}})
# Test case checker_type:checker_opt:checker_val
opt_dict = cchecker.parse_options(
["type:opt:val", "type:opt2:val:2", "cf:enable_appendix_a_checks"],
)
assert opt_dict == defaultdict(
dict,
{
"type": {"opt": "val", "opt2": "val:2"},
"cf": {"enable_appendix_a_checks": None},
},
)

0 comments on commit 8f96172

Please sign in to comment.