Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding inputs (i.e. options incl. value) #1091

Merged
merged 6 commits into from
Jul 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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},
},
)
Loading