diff --git a/mylib/config.py b/mylib/config.py index a94e0c0..26f7fb2 100644 --- a/mylib/config.py +++ b/mylib/config.py @@ -218,6 +218,18 @@ class BooleanOption(BaseOption): def parser_type(self): return None + @property + def parser_argument_name(self): + """ Get option argument name in parser options """ + return ( + self.arg if self.arg else + '--{0}-{1}-{2}'.format( + self.section.name, + 'enable' if not self.default else 'disable', + self.name + ).lower().replace('_', '-') + ) + class FloatOption(BaseOption): """ Float configuration option class """ @@ -389,6 +401,7 @@ class Config: self.options = None self.sections = {} self._loaded_callbacks = [] + self._loaded_callbacks_executed = [] self._filepath = None def add_section(self, name, loaded_callback=None, **kwargs): @@ -406,8 +419,8 @@ class Config: if loaded_callback: self._loaded_callbacks.append(loaded_callback) # If configuration is already loaded, execute callback immediatly - if self._filepath: - loaded_callback(self) + if self.config_parser or self.options: + self._loaded() return self.sections[name] def defined(self, section, option): @@ -434,7 +447,7 @@ class Config: section, option), 'Unknown option %s.%s' % (section, option) self.sections[section].set(option, value) - def load_file(self, filepath): + def load_file(self, filepath, execute_callback=True): """ Read configuration file """ self.config_parser = ConfigParser() @@ -469,12 +482,19 @@ class Config: self._filepath = filepath - # Execute loaded callbacks - for callback in self._loaded_callbacks: - callback(self) + if execute_callback: + self._loaded() return True + def _loaded(self): + """ Execute loaded callbacks """ + for callback in self._loaded_callbacks: + if callback in self._loaded_callbacks_executed: + continue + callback(self) + self._loaded_callbacks_executed.append(callback) + def save(self, filepath=None): """ Save configuration file """ filepath = filepath if filepath else self._filepath @@ -571,7 +591,8 @@ class Config: """ parser = parser if parser else self.get_arguments_parser() argcomplete.autocomplete(parser) - options = parser.parse_args(argv if argv else sys.argv[1:]) + options = parser.parse_args(argv if argv is not None else sys.argv[1:]) + self.load_options(options, execute_callback=False) if options.config: options.config = os.path.abspath(options.config) @@ -588,7 +609,7 @@ class Config: already_saved = True # Load configuration file - if os.path.isfile(options.config) and not self.load_file(options.config): + if os.path.isfile(options.config) and not self.load_file(options.config, execute_callback=False): parser.error( 'Failed to load configuration from file %s' % options.config ) @@ -602,14 +623,17 @@ class Config: elif options.verbose: logging.getLogger().setLevel(logging.INFO) - self.load_options(options) + self._loaded() + return options - def load_options(self, options): + def load_options(self, options, execute_callback=True): """ Register arguments parser options """ assert isinstance(options, argparse.Namespace) self.options = options log.debug('Argument options: %s', options) + if execute_callback: + self._loaded() def add_options_to_parser(self, parser): """ Add sections and their options to parser """