config: add ConfigurableObject object class

This commit is contained in:
Benjamin Renard 2022-01-19 17:21:05 +01:00
parent 0823353c0a
commit ba4e85be50

View file

@ -948,3 +948,87 @@ class Config: # pylint: disable=too-many-instance-attributes
("%s.ini" % self.shortname) if self.shortname
else "config.ini"
)
class ConfigurableObject:
"""
Base class of configurable object
This class provide a way to configure an object using :
- mylib.config.Config object
- argparse.Namespace object
- kwargs passed to __init__ method
"""
# Configuration object name (used for default options prefix and config section)
# Note: required if options_prefix or/and config_section parameters not provided
# to __init__ method.
_config_name = None
# Configuration comment (used for config section)
_config_comment = None
# Default options value
# Important: all supported options MUST HAVE a default value defined
_defaults = {}
# Store options passed throuht __init__ method
_kwargs = {}
_options = {}
_options_prefix = None
_config = None
_config_section = None
def __init__(self, options=None, options_prefix=None, config=None, config_section=None,
**kwargs):
for key, value in kwargs.items():
assert key in self._defaults, "Unknown %s option" % key
self._kwargs[key] = value
if options:
self._options = options
if options_prefix is not None:
self._options_prefix = options_prefix
elif self._config_name:
self._options_prefix = self._config_name + '_'
else:
raise Exception('No configuration name defined for %s' % __name__)
if config:
self._config = config
if config_section:
self._config_section = config_section
elif self._config_name:
self._config_section = self._config_name
else:
raise Exception('No configuration name defined for %s' % __name__)
def _get_option(self, option, default=None, required=False):
""" Retreive option value """
if self._kwargs and option in self._kwargs:
return self._kwargs[option]
if self._options and hasattr(self._options, self._options_prefix + option):
return getattr(self._options, self._options_prefix + option)
if self._config and self._config.defined(self._config_section, option):
return self._config.get(self._config_section, option)
assert not required, "Options %s not defined" % option
return default if default is not None else self._defaults.get(option)
def configure(self, comment=None, ** kwargs):
""" Configure options on registered mylib.Config object """
assert self._config, "mylib.Config object not registered. Must be passed to __init__ as config keyword argument."
return self._config.add_section(
self._config_section,
comment=comment if comment else self._config_comment,
loaded_callback=self.initialize, **kwargs)
def initialize(self, loaded_config=None):
""" Configuration initialized hook """
if loaded_config:
self.config = loaded_config # pylint: disable=attribute-defined-outside-init