from ScEpTIC.exceptions import ConfigurationException class ScEpTICBaseConfig: """ ScEpTIC sub-functions base configuration class """ # Each configuration parameter must specify: # 'class' -> the class type of the parameter's value # 'mode' -> the allowed configuration method (set / add) # Optionals: # 'values' -> list of allowed values for the parameter ( 'class' must be set to 'specific') # 'value_check_function' -> function that checks if the provided value is correct _config_domain = {} def __init__(self, main_config): """ :param main_config: main configuration container """ self._main_config = main_config def _check(self, config_name, config_value, mode): """ Checks the values of a configuration parameter :param config_name: the configuration name :param config_value: the configuration value :param mode: the configuration method """ domain = self._config_domain[config_name] if domain['mode'] != mode: raise ConfigurationException(f"[{self.__class__.__name__}] Wrong configuration mode '{mode}_config()' for {config_name}. Only '{domain['mode']}_config()' is allowed") if domain['class'] == 'specific': if config_value not in domain['values']: raise ConfigurationException(f"[{self.__class__.__name__}] Wrong value for {config_name}: {config_value} not allowed.") elif not isinstance(config_value, domain['class']): raise ConfigurationException(f"[{self.__class__.__name__}] Wrong value for {config_name}. {domain['class']} required, but {config_value.__class__.__name__} was given.") if 'value_check_function' in domain: if not domain['value_check_function'](config_value): raise ConfigurationException(f"[{self.__class__.__name__}] Wrong value for {config_name}: {config_value} not allowed.") def set_config(self, config_name, config_value): """ Sets a configuration parameter :param config_name: the configuration name :param config_value: the configuration value """ self._check(config_name, config_value, 'set') setattr(self, config_name, config_value) self._check_callback(config_name, config_value) def add_config(self, config_name, config_value): """ Adds a configuration parameter :param config_name: the configuration name :param config_value: the configuration value """ self._check(config_name, config_value, 'add') getattr(self, config_name).append(config_value) self._check_callback(config_name, config_value) def _register_config_callback(self, config_name, callback): """ Registers a configuration callback that executes whenever config_name is changed :param config_name: the configuration name :param callback: the callback function """ if config_name == '*': for name in self._config_domain.keys(): self._config_domain[name]['callback'] = callback else: self._config_domain[config_name]['callback'] = callback def _check_callback(self, config_name, config_value): """ Check if config_name has a configuration callback function and executes it :param config_name: the configuration name :param config_value: the configuration value """ if 'callback' in self._config_domain[config_name]: self._config_domain[config_name]['callback'](config_name, config_value)