From e1c1340629f3917a4872d4c28b7c3488ab7f5142 Mon Sep 17 00:00:00 2001 From: Aaron LI Date: Fri, 4 Nov 2016 11:12:51 +0800 Subject: configs: Rename "validate.py" and update "validate_configs()" * Rename "validate.py" to "checkers.py", to avoid the confusion with the "validate" module from "configobj"; * Rename function "validate_configs()" to "check_configs()"; * "check_configs()": add optional parameter "raise_exception"; * "check_configs()": update to return both the result and errors dict. --- fg21sim/configs/checkers.py | 179 ++++++++++++++++++++++++++++++++++++++++++++ fg21sim/configs/validate.py | 167 ----------------------------------------- 2 files changed, 179 insertions(+), 167 deletions(-) create mode 100644 fg21sim/configs/checkers.py delete mode 100644 fg21sim/configs/validate.py diff --git a/fg21sim/configs/checkers.py b/fg21sim/configs/checkers.py new file mode 100644 index 0000000..e225234 --- /dev/null +++ b/fg21sim/configs/checkers.py @@ -0,0 +1,179 @@ +# Copyright (c) 2016 Weitian LI +# MIT license + +""" +Custom checkers to further validate the configurations. + +NOTE +---- +These functions further check the configurations as a whole, which means +one config option may be checked against its context. +Therefore, they are very different to the checker functions used in the +``validate.Validator``. +""" + +import os + +from ..errors import ConfigError + + +def _check_missing(configs, keys): + """Check whether the required config is provided by the user.""" + results = {} + if isinstance(keys, str): + keys = [keys, ] + for key in keys: + if not configs.getn(key): + results[key] = "Value required but missing" + return results + + +def _check_existence(configs, keys): + """Check whether the file/directory corresponding to the config exists.""" + if isinstance(keys, str): + keys = [keys, ] + results = {} + for key in keys: + res = _check_missing(configs, key) + if res == {}: + # Both "key" and "dir_key" are valid + path = configs.get_path(key) + if not os.path.exists(path): + res[key] = 'File/directory not exist: "%s"' % path + results.update(res) + return results + + +def check_frequency(configs): + """Check the "[frequency]" section of the configurations.""" + results = {} + if configs.getn("frequency/type") == "custom": + results.update(_check_missing(configs, "frequency/frequencies")) + elif configs.getn("frequency/type") == "calc": + results.update( + _check_missing(configs, ["frequency/start", + "frequency/stop", + "frequency/step"]) + ) + return results + + +def check_output(configs): + """Check the "[output]" section of the configurations.""" + results = {} + if configs.getn("output/combine"): + results.update(_check_missing(configs, "output/output_dir")) + return results + + +def check_galactic_synchrotron(configs): + """Check the "[galactic][synchrotron]" section of the configurations.""" + comp = "galactic/synchrotron" + comp_enabled = configs.getn("common/components") + results = {} + if comp in comp_enabled: + # Only validate the configs if this component is enabled + results.update( + _check_missing(configs, [comp+"/template_freq", + comp+"/template_unit"]) + ) + results.update( + _check_existence(configs, [comp+"/template", comp+"/indexmap"]) + ) + if configs.getn(comp+"/save"): + results.update(_check_missing(configs, comp+"/output_dir")) + return results + + +def check_galactic_freefree(configs): + """Check the "[galactic][freefree]" section of the configurations.""" + comp = "galactic/freefree" + comp_enabled = configs.getn("common/components") + results = {} + if comp in comp_enabled: + # Only validate the configs if this component is enabled + results.update( + _check_missing(configs, [comp+"/halphamap_unit", + comp+"/dustmap_unit"]) + ) + results.update( + _check_existence(configs, [comp+"/halphamap", comp+"/dustmap"]) + ) + if configs.getn(comp+"/save"): + results.update(_check_missing(configs, comp+"/output_dir")) + return results + + +def check_galactic_snr(configs): + """Check the "[galactic][snr]" section of the configurations.""" + comp = "galactic/snr" + comp_enabled = configs.getn("common/components") + results = {} + if comp in comp_enabled: + # Only validate the configs if this component is enabled + results.update( + _check_existence(configs, comp+"/catalog") + ) + if configs.getn(comp+"/save"): + results.update(_check_missing(configs, comp+"/output_dir")) + return results + + +# Available checkers to validate the configurations +_CHECKERS = [ + check_frequency, + check_output, + check_galactic_synchrotron, + check_galactic_freefree, + check_galactic_snr, +] + + +def check_configs(configs, raise_exception=True, checkers=_CHECKERS): + """Check/validate the whole configurations through all the supplied + checker functions. + + These checker functions may check one config option against its context + if necessary to determine whether it has a valid value. + + Parameters + ---------- + configs : `ConfigManager` instance + An ``ConfigManager`` instance contains both default and user + configurations. + raise_exception : bool, optional + Whether raise a ``ConfigError`` exception if there is any invalid + config options? + checkers : list of functions, optional + List of checker functions through which the configurations + will be checked. + + Returns + ------- + result : bool + ``True`` if the configurations pass all checker functions. + errors : dict + An dictionary containing the details about the invalid config options, + with the keys identifying the config options and values indicating + the error message. + If above ``result=True``, then this is an empty dictionary ``{}``. + + Raises + ------ + ConfigError + If any config option failed to pass any of the checkers, a + ``ConfigError`` with details is raised. + """ + errors = {} + for checker in checkers: + errors.update(checker(configs)) + # + if errors == {}: + result = True + else: + result = False + if raise_exception: + msg = "\n".join(['Config "{key}": {val}'.format(key=key, val=val) + for key, val in errors.items()]) + raise ConfigError(msg) + return (result, errors) diff --git a/fg21sim/configs/validate.py b/fg21sim/configs/validate.py deleted file mode 100644 index 0fd2c64..0000000 --- a/fg21sim/configs/validate.py +++ /dev/null @@ -1,167 +0,0 @@ -# Copyright (c) 2016 Weitian LI -# MIT license - -""" -Custom validations for the configurations. - -NOTE ----- -These checker functions check the configurations as a whole, and may check -a config item against its context, -Therefore, they are very different to the checker function of `Validator`. -""" - -import os - -from ..errors import ConfigError - - -def _check_missing(configs, keys): - """Check whether the required config is provided by the user.""" - results = {} - if isinstance(keys, str): - keys = [keys, ] - for key in keys: - if not configs.getn(key): - results[key] = "Value required but missing" - return results - - -def _check_existence(configs, keys): - """Check whether the file/directory corresponding to the config exists.""" - if isinstance(keys, str): - keys = [keys, ] - results = {} - for key in keys: - res = _check_missing(configs, key) - if res == {}: - # Both "key" and "dir_key" are valid - path = configs.get_path(key) - if not os.path.exists(path): - res[key] = 'File/directory not exist: "%s"' % path - results.update(res) - return results - - -def check_frequency(configs): - """Check the "[frequency]" section of the configurations.""" - results = {} - if configs.getn("frequency/type") == "custom": - results.update(_check_missing(configs, "frequency/frequencies")) - elif configs.getn("frequency/type") == "calc": - results.update( - _check_missing(configs, ["frequency/start", - "frequency/stop", - "frequency/step"]) - ) - return results - - -def check_output(configs): - """Check the "[output]" section of the configurations.""" - results = {} - if configs.getn("output/combine"): - results.update(_check_missing(configs, "output/output_dir")) - return results - - -def check_galactic_synchrotron(configs): - """Check the "[galactic][synchrotron]" section of the configurations.""" - comp = "galactic/synchrotron" - comp_enabled = configs.getn("common/components") - results = {} - if comp in comp_enabled: - # Only validate the configs if this component is enabled - results.update( - _check_missing(configs, [comp+"/template_freq", - comp+"/template_unit"]) - ) - results.update( - _check_existence(configs, [comp+"/template", comp+"/indexmap"]) - ) - if configs.getn(comp+"/save"): - results.update(_check_missing(configs, comp+"/output_dir")) - return results - - -def check_galactic_freefree(configs): - """Check the "[galactic][freefree]" section of the configurations.""" - comp = "galactic/freefree" - comp_enabled = configs.getn("common/components") - results = {} - if comp in comp_enabled: - # Only validate the configs if this component is enabled - results.update( - _check_missing(configs, [comp+"/halphamap_unit", - comp+"/dustmap_unit"]) - ) - results.update( - _check_existence(configs, [comp+"/halphamap", comp+"/dustmap"]) - ) - if configs.getn(comp+"/save"): - results.update(_check_missing(configs, comp+"/output_dir")) - return results - - -def check_galactic_snr(configs): - """Check the "[galactic][snr]" section of the configurations.""" - comp = "galactic/snr" - comp_enabled = configs.getn("common/components") - results = {} - if comp in comp_enabled: - # Only validate the configs if this component is enabled - results.update( - _check_existence(configs, comp+"/catalog") - ) - if configs.getn(comp+"/save"): - results.update(_check_missing(configs, comp+"/output_dir")) - return results - - -# Available checkers to validate the configurations -_CHECKERS = [ - check_frequency, - check_output, - check_galactic_synchrotron, - check_galactic_freefree, - check_galactic_snr, -] - - -def validate_configs(configs, checkers=_CHECKERS): - """Validate the configurations through the supplied checkers. - - These checker usually validate on the global scale, and validate - some specific configs against their contexts. - - Parameters - ---------- - configs : `ConfigManager` object - An `ConfigManager` object contains both default and user - configurations. - checkers : list of functions - List of checker functions through which the configurations - will be validated. - - Returns - ------- - bool - True if the configurations pass all checker functions, otherwise, - the `ConfigError` will be raised with corresponding message. - - Raises - ------ - ConfigError - If any configuration failed the check, a `ConfigError` with - details will be raised. - """ - results = {} - for checker in checkers: - results.update(checker(configs)) - # - if results == {}: - return True - else: - err_msg = "\n".join(['Config "{key}": {msg}'.format(key=key, msg=msg) - for key, msg in results.items()]) - raise ConfigError(err_msg) -- cgit v1.2.2