From 55782df47c3790ac9654b22aff307462f113b8af Mon Sep 17 00:00:00 2001 From: Benjamin Renard Date: Fri, 6 Jan 2023 18:16:46 +0100 Subject: [PATCH] config: code cleaning --- mylib/config.py | 107 +++++++++++++++++++++++++++--------------------- 1 file changed, 60 insertions(+), 47 deletions(-) diff --git a/mylib/config.py b/mylib/config.py index cb7bfc0..a6ab0de 100644 --- a/mylib/config.py +++ b/mylib/config.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +# pylint: disable=too-many-lines """ Configuration & options parser """ @@ -136,14 +137,17 @@ class BaseOption: # pylint: disable=too-many-instance-attributes @property def parser_dest(self): """ Get option name in arguments parser options """ - return '{0}_{1}'.format(self.section.name, self.name) + return f'{self.section.name}_{self.name}' @property def parser_help(self): """ Get option help message in arguments parser options """ if self.arg_help and self.default is not None: + # pylint: disable=consider-using-f-string return '{0} (Default: {1})'.format( - self.arg_help, re.sub(r'%([^%])', r'%%\1', str(self.default))) + self.arg_help, + re.sub(r'%([^%])', r'%%\1', str(self._default_in_config)) + ) if self.arg_help: return self.arg_help return None @@ -153,9 +157,7 @@ class BaseOption: # pylint: disable=too-many-instance-attributes """ Get option argument name in parser options """ return ( self.arg if self.arg else - '--{0}-{1}'.format( - self.section.name, self.name - ).lower().replace('_', '-') + f'--{self.section.name}-{self.name}'.lower().replace('_', '-') ) def add_option_to_parser(self, section_opts): @@ -292,6 +294,7 @@ class BooleanOption(BaseOption): @property def parser_argument_name(self): """ Get option argument name in parser options """ + # pylint: disable=consider-using-f-string return ( self.arg if self.arg else '--{0}-{1}-{2}'.format( @@ -304,7 +307,7 @@ class BooleanOption(BaseOption): def _ask_value(self, prompt=None, **kwargs): """ Ask to user to enter value of this option and return it """ default_value = self.get() - prompt = "%s: " % self.name + prompt = f'{self.name}: ' if default_value: prompt += '[Y/n] ' else: @@ -413,12 +416,11 @@ class PasswordOption(StringOption): value = keyring.get_password(service_name, username) if value is None: + # pylint: disable=consider-using-f-string value = getpass( - 'Please enter %s%s: ' % ( - self.comment if self.comment else - '%s %s' % (self.section.name, self.name), - (' for %s' % username) - if username != self.name else '' + 'Please enter {0}{1}: '.format( + f'{self.section.name} {self.name}', + f' for {username}' if username != self.name else '' ) ) keyring.set_password(service_name, username, value) @@ -445,11 +447,11 @@ class PasswordOption(StringOption): print('# ' + self.comment) default_value = kwargs.pop('default_value', self.get()) if not prompt: - prompt = '%s: ' % self.name + prompt = f'{self.name}: ' if default_value is not None: # Hide value only if it differed from default value if default_value == self.default: - prompt += '[%s] ' % default_value + prompt += f'[{default_value}] ' else: prompt += '[secret defined, leave to empty to keep it as unchange] ' value = getpass(prompt) @@ -466,8 +468,8 @@ class PasswordOption(StringOption): default_use_keyring = (super().get() == self.keyring_value) while use_keyring is None: prompt = ( - 'Do you want to use XDG keyring ? [%s] ' % - ('Y/n' if default_use_keyring else 'y/N') + 'Do you want to use XDG keyring ? ' + f"[{'Y/n' if default_use_keyring else 'y/N'}] " ) result = input(prompt).lower() if result == '': @@ -488,7 +490,7 @@ class ConfigSection: def __init__(self, config, name, comment=None, order=None): self.config = config self.name = name - self.options = dict() + self.options = {} self.comment = comment self.order = order if isinstance(order, int) else 10 @@ -500,7 +502,7 @@ class ConfigSection: :param name: Option name :param **kwargs: Dict of raw option for type class """ - assert not self.defined(name), "Duplicated option %s" % name + assert not self.defined(name), f'Duplicated option {name}' self.options[name] = _type(self.config, self, name, **kwargs) return self.options[name] @@ -514,12 +516,12 @@ class ConfigSection: def get(self, option): """ Get option value """ - assert self.defined(option), "Option %s unknown" % option + assert self.defined(option), f'Option {option} unknown' return self.options[option].get() def set(self, option, value): """ Set option value """ - assert self.defined(option), "Option %s unknown" % option + assert self.defined(option), f'Option {option} unknown' return self.options[option].set(value) def add_options_to_parser(self, parser): @@ -530,16 +532,16 @@ class ConfigSection: else self.name.capitalize() ) - for option in self.options: + for option in self.options: # pylint: disable=consider-using-dict-items self.options[option].add_option_to_parser(section_opts) def export_to_config(self): """ Export section and their options to configuration file """ lines = [] if self.comment: - lines.append('# %s' % self.comment) - lines.append('[%s]' % self.name) - for option in self.options: + lines.append(f'# {self.comment}') + lines.append(f'[{self.name}]') + for option in self.options: # pylint: disable=consider-using-dict-items lines.append(self.options[option].export_to_config()) return '\n'.join(lines) @@ -555,9 +557,9 @@ class ConfigSection: :rtype: bool of dict """ if self.comment: - print('# %s' % self.comment) - print('[%s]\n' % self.name) - result = dict() + print(f'# {self.comment}') + print(f'[{self.name}]''\n') + result = {} error = False for name, option in self.options.items(): option_result = option.ask_value(set_it=set_it) @@ -622,7 +624,7 @@ class Config: # pylint: disable=too-many-instance-attributes The specified callback method will receive Config object as parameter. : param ** kwargs: Raw parameters dict pass to ConfigSection __init__() method """ - assert name not in self.sections, "Duplicated section %s" % name + assert name not in self.sections, f'Duplicated section {name}' self.sections[name] = ConfigSection(self, name, **kwargs) if loaded_callback: @@ -644,7 +646,7 @@ class Config: # pylint: disable=too-many-instance-attributes """ Get option value """ assert self.config_parser or self.options, 'Unconfigured options parser' assert self.defined( - section, option), 'Unknown option %s.%s' % (section, option) + section, option), f'Unknown option {section}.{option}' value = self.sections[section].get(option) log.debug('get(%s, %s): %s (%s)', section, option, value, type(value)) return value @@ -664,7 +666,7 @@ class Config: # pylint: disable=too-many-instance-attributes """ Set option value """ assert self.config_parser, 'Unconfigured options parser' assert self.defined( - section, option), 'Unknown option %s.%s' % (section, option) + section, option), f'Unknown option {section}.{option}' self.sections[section].set(option, value) def load_file(self, filepath, execute_callback=True): @@ -734,7 +736,11 @@ class Config: # pylint: disable=too-many-instance-attributes 'Configuration directory "%s" does not exist (or not writable)', dirpath) return False - lines = ['#\n# %s configuration\n#\n' % self.appname] + lines = [ + '#\n' + f'# {self.appname} configuration' + '\n#\n' + ] for section_name in self._ordered_section_names: lines.append('') @@ -769,9 +775,15 @@ class Config: # pylint: disable=too-many-instance-attributes formatter_class=RawWrappedTextHelpFormatter, **kwargs) - config_file_help = 'Configuration file to use (default: %s)' % self.config_filepath + config_file_help = ( + f'Configuration file to use (default: {self.config_filepath})' + ) if self.config_file_env_variable: - config_file_help += '\n\nYou also could set %s environment variable to specify your configuration file path.' % self.config_file_env_variable + config_file_help += ( + '\n\nYou also could set ' + f'{self.config_file_env_variable} environment variable to ' + 'specify your configuration file path.' + ) self.options_parser.add_argument( '-c', '--config', @@ -854,7 +866,7 @@ class Config: # pylint: disable=too-many-instance-attributes # Load configuration file 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 + f'Failed to load configuration from file {options.config}' ) if options.save and not already_saved: @@ -907,7 +919,7 @@ class Config: # pylint: disable=too-many-instance-attributes # On set it mode, ensure configuration file parser is initialized if set_it and not self.config_parser: self.config_parser = ConfigParser() - result = dict() + result = {} error = False for name, section in self.sections.items(): section_result = section.ask_values(set_it=set_it) @@ -960,14 +972,14 @@ class Config: # pylint: disable=too-many-instance-attributes argv, create=False, execute_callback=False) if os.path.exists(options.config) and not options.overwrite: - print('Configuration file %s already exists' % options.config) + print(f'Configuration file {options.config} already exists') sys.exit(1) if options.interactive: self.ask_values(set_it=True) if self.save(options.config): - print('Configuration file %s created.' % options.config) + print(f'Configuration file {options.config} created.') if options.validate: print('Validate your configuration...') try: @@ -976,14 +988,15 @@ class Config: # pylint: disable=too-many-instance-attributes else: print('Error(s) occurred validating your configuration. See logs for details.') sys.exit(1) - except Exception: + except Exception: # pylint: disable=broad-except print( - 'Exception occurred validating your configuration: %s\n\nSee logs for details.' % - traceback.format_exc()) + 'Exception occurred validating your configuration:\n' + f'{traceback.format_exc()}' + '\n\nSee logs for details.' + ) sys.exit(2) else: - print('Error occured creating configuration file %s' % - options.config) + print(f'Error occured creating configuration file {options.config}') sys.exit(1) sys.exit(0) @@ -1006,8 +1019,8 @@ class Config: # pylint: disable=too-many-instance-attributes return os.environ.get(self.config_file_env_variable) return os.path.join( self.config_dir, - ("%s.ini" % self.shortname) if self.shortname - else "config.ini" + f'{self.shortname}.ini' if self.shortname + else 'config.ini' ) @@ -1044,7 +1057,7 @@ class ConfigurableObject: **kwargs): for key, value in kwargs.items(): - assert key in self._defaults, "Unknown %s option" % key + assert key in self._defaults, f'Unknown {key} option' self._kwargs[key] = value if options: @@ -1054,7 +1067,7 @@ class ConfigurableObject: elif self._config_name: self._options_prefix = self._config_name + '_' else: - raise Exception('No configuration name defined for %s' % __name__) + raise Exception(f'No configuration name defined for {__name__}') if config: self._config = config @@ -1063,7 +1076,7 @@ class ConfigurableObject: elif self._config_name: self._config_section = self._config_name else: - raise Exception('No configuration name defined for %s' % __name__) + raise Exception(f'No configuration name defined for {__name__}') def _get_option(self, option, default=None, required=False): """ Retreive option value """ @@ -1076,7 +1089,7 @@ class ConfigurableObject: 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 + assert not required, f'Options {option} not defined' return default if default is not None else self._defaults.get(option)