diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 85377edb..2399c1d4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -28,3 +28,8 @@ repos: hooks: - id: bandit args: ['-x', 'tests'] + - repo: https://github.com/asottile/pyupgrade + rev: v3.18.0 + hooks: + - id: pyupgrade + args: [--py3-only] diff --git a/doc/source/conf.py b/doc/source/conf.py index 975740fb..8e6f151c 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright (C) 2020 Red Hat, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may diff --git a/oslo_config/cfg.py b/oslo_config/cfg.py index 672eaa0a..58982616 100644 --- a/oslo_config/cfg.py +++ b/oslo_config/cfg.py @@ -106,7 +106,8 @@ class NoSuchOptError(Error, AttributeError): def __str__(self): group_name = 'DEFAULT' if self.group is None else self.group.name - return "no such option %s in group [%s]" % (self.opt_name, group_name) + return "no such option {} in group [{}]".format( + self.opt_name, group_name) class NoSuchGroupError(Error): @@ -138,8 +139,8 @@ class RequiredOptError(Error): def __str__(self): group_name = 'DEFAULT' if self.group is None else self.group.name - return "value required for option %s in group [%s]" % (self.opt_name, - group_name) + return "value required for option {} in group [{}]".format( + self.opt_name, group_name) class TemplateSubstitutionError(Error): @@ -189,7 +190,7 @@ class ConfigFileParseError(Error): self.msg = msg def __str__(self): - return 'Failed to parse %s: %s' % (self.config_file, self.msg) + return 'Failed to parse {}: {}'.format(self.config_file, self.msg) class ConfigSourceValueError(Error, ValueError): @@ -260,7 +261,7 @@ def _search_dirs(dirs, basename, extension=""): :returns: the path to a matching file or directory, or None """ for d in dirs: - path = os.path.join(d, '%s%s' % (basename, extension)) + path = os.path.join(d, '{}{}'.format(basename, extension)) if os.path.exists(path): return path @@ -538,7 +539,7 @@ class Opt: deprecated_for_removal=False, deprecated_reason=None, deprecated_since=None, mutable=False, advanced=False): if name.startswith('_'): - raise ValueError('illegal name %s with prefix _' % (name,)) + raise ValueError('illegal name {} with prefix _'.format(name)) self.name = name if type is None: @@ -917,14 +918,14 @@ class StrOpt(Opt): def __init__(self, name, choices=None, quotes=None, regex=None, ignore_case=False, max_length=None, **kwargs): - super(StrOpt, self).__init__(name, - type=types.String( - choices=choices, - quotes=quotes, - regex=regex, - ignore_case=ignore_case, - max_length=max_length), - **kwargs) + super().__init__(name, + type=types.String( + choices=choices, + quotes=quotes, + regex=regex, + ignore_case=ignore_case, + max_length=max_length), + **kwargs) def _get_choice_text(self, choice): if choice is None: @@ -935,7 +936,7 @@ class StrOpt(Opt): def _get_argparse_kwargs(self, group, **kwargs): """Extends the base argparse keyword dict for the config dir option.""" - kwargs = super(StrOpt, self)._get_argparse_kwargs(group) + kwargs = super()._get_argparse_kwargs(group) if getattr(self.type, 'choices', None): choices_text = ', '.join([self._get_choice_text(choice) @@ -965,11 +966,11 @@ class BoolOpt(Opt): def __init__(self, name, **kwargs): if 'positional' in kwargs: raise ValueError('positional boolean args not supported') - super(BoolOpt, self).__init__(name, type=types.Boolean(), **kwargs) + super().__init__(name, type=types.Boolean(), **kwargs) def _add_to_cli(self, parser, group=None): """Extends the base class method to add the --nooptname option.""" - super(BoolOpt, self)._add_to_cli(parser, group) + super()._add_to_cli(parser, group) self._add_inverse_to_argparse(parser, group) def _add_inverse_to_argparse(self, parser, group): @@ -991,7 +992,7 @@ class BoolOpt(Opt): def _get_argparse_kwargs(self, group, action='store_true', **kwargs): """Extends the base argparse keyword dict for boolean options.""" - kwargs = super(BoolOpt, self)._get_argparse_kwargs(group, **kwargs) + kwargs = super()._get_argparse_kwargs(group, **kwargs) # type has no effect for BoolOpt, it only matters for # values that came from config files if 'type' in kwargs: @@ -1030,12 +1031,12 @@ class IntOpt(Opt): """ def __init__(self, name, min=None, max=None, choices=None, **kwargs): - super(IntOpt, self).__init__(name, - type=types.Integer( - min=min, - max=max, - choices=choices), - **kwargs) + super().__init__(name, + type=types.Integer( + min=min, + max=max, + choices=choices), + **kwargs) class FloatOpt(Opt): @@ -1055,8 +1056,7 @@ class FloatOpt(Opt): """ def __init__(self, name, min=None, max=None, **kwargs): - super(FloatOpt, self).__init__(name, type=types.Float(min, max), - **kwargs) + super().__init__(name, type=types.Float(min, max), **kwargs) class ListOpt(Opt): @@ -1075,10 +1075,10 @@ class ListOpt(Opt): """ def __init__(self, name, item_type=None, bounds=None, **kwargs): - super(ListOpt, self).__init__(name, - type=types.List(item_type=item_type, - bounds=bounds), - **kwargs) + super().__init__(name, + type=types.List(item_type=item_type, + bounds=bounds), + **kwargs) class DictOpt(Opt): @@ -1094,7 +1094,7 @@ class DictOpt(Opt): """ def __init__(self, name, **kwargs): - super(DictOpt, self).__init__(name, type=types.Dict(), **kwargs) + super().__init__(name, type=types.Dict(), **kwargs) class IPOpt(Opt): @@ -1112,8 +1112,8 @@ class IPOpt(Opt): """ def __init__(self, name, version=None, **kwargs): - super(IPOpt, self).__init__(name, type=types.IPAddress(version), - **kwargs) + super().__init__(name, type=types.IPAddress(version), + **kwargs) class PortOpt(Opt): @@ -1144,7 +1144,7 @@ class PortOpt(Opt): def __init__(self, name, min=None, max=None, choices=None, **kwargs): type = types.Port(min=min, max=max, choices=choices, type_name='port value') - super(PortOpt, self).__init__(name, type=type, **kwargs) + super().__init__(name, type=type, **kwargs) class HostnameOpt(Opt): @@ -1160,8 +1160,8 @@ class HostnameOpt(Opt): """ def __init__(self, name, **kwargs): - super(HostnameOpt, self).__init__(name, type=types.Hostname(), - **kwargs) + super().__init__(name, type=types.Hostname(), + **kwargs) class HostAddressOpt(Opt): @@ -1181,9 +1181,9 @@ class HostAddressOpt(Opt): """ def __init__(self, name, version=None, **kwargs): - super(HostAddressOpt, self).__init__(name, - type=types.HostAddress(version), - **kwargs) + super().__init__(name, + type=types.HostAddress(version), + **kwargs) class HostDomainOpt(Opt): @@ -1203,9 +1203,9 @@ class HostDomainOpt(Opt): """ def __init__(self, name, version=None, **kwargs): - super(HostDomainOpt, self).__init__(name, - type=types.HostDomain(version), - **kwargs) + super().__init__(name, + type=types.HostDomain(version), + **kwargs) class URIOpt(Opt): @@ -1230,7 +1230,7 @@ class URIOpt(Opt): def __init__(self, name, max_length=None, schemes=None, **kwargs): type = types.URI(max_length=max_length, schemes=schemes) - super(URIOpt, self).__init__(name, type=type, **kwargs) + super().__init__(name, type=type, **kwargs) class MultiOpt(Opt): @@ -1259,11 +1259,11 @@ class MultiOpt(Opt): multi = True def __init__(self, name, item_type, **kwargs): - super(MultiOpt, self).__init__(name, item_type, **kwargs) + super().__init__(name, item_type, **kwargs) def _get_argparse_kwargs(self, group, **kwargs): """Extends the base argparse keyword dict for multi value options.""" - kwargs = super(MultiOpt, self)._get_argparse_kwargs(group) + kwargs = super()._get_argparse_kwargs(group) if not self.positional: kwargs['action'] = 'append' else: @@ -1283,9 +1283,9 @@ class MultiStrOpt(MultiOpt): """ def __init__(self, name, **kwargs): - super(MultiStrOpt, self).__init__(name, - item_type=types.MultiString(), - **kwargs) + super().__init__(name, + item_type=types.MultiString(), + **kwargs) class SubCommandOpt(Opt): @@ -1321,8 +1321,8 @@ class SubCommandOpt(Opt): this subparsers object can be used to register parsers for sub-commands. """ - super(SubCommandOpt, self).__init__(name, type=types.String(), - dest=dest, help=help) + super().__init__(name, type=types.String(), + dest=dest, help=help) self.handler = handler self.title = title self.description = description @@ -1384,11 +1384,11 @@ class _ConfigFileOpt(Opt): ConfigParser._parse_file(values, namespace) def __init__(self, name, **kwargs): - super(_ConfigFileOpt, self).__init__(name, lambda x: x, **kwargs) + super().__init__(name, lambda x: x, **kwargs) def _get_argparse_kwargs(self, group, **kwargs): """Extends the base argparse keyword dict for the config file opt.""" - kwargs = super(_ConfigFileOpt, self)._get_argparse_kwargs(group) + kwargs = super()._get_argparse_kwargs(group) kwargs['action'] = self.ConfigFileAction return kwargs @@ -1439,12 +1439,12 @@ class _ConfigDirOpt(Opt): ConfigParser._parse_file(config_file, namespace) def __init__(self, name, **kwargs): - super(_ConfigDirOpt, self).__init__(name, type=types.List(), - **kwargs) + super().__init__(name, type=types.List(), + **kwargs) def _get_argparse_kwargs(self, group, **kwargs): """Extends the base argparse keyword dict for the config dir option.""" - kwargs = super(_ConfigDirOpt, self)._get_argparse_kwargs(group) + kwargs = super()._get_argparse_kwargs(group) kwargs['action'] = self.ConfigDirAction return kwargs @@ -1559,7 +1559,7 @@ class OptGroup: class ParseError(iniparser.ParseError): def __init__(self, msg, lineno, line, filename): - super(ParseError, self).__init__(msg, lineno, line) + super().__init__(msg, lineno, line) self.filename = filename def __str__(self): @@ -1578,7 +1578,7 @@ class ConfigParser(iniparser.BaseParser): """ def __init__(self, filename, sections): - super(ConfigParser, self).__init__() + super().__init__() self.filename = filename self.sections = sections self._normalized = None @@ -1589,7 +1589,7 @@ class ConfigParser(iniparser.BaseParser): def parse(self): with open(self.filename) as f: - return super(ConfigParser, self).parse(f.readlines()) + return super().parse(f.readlines()) def new_section(self, section): self.section = section @@ -1637,7 +1637,7 @@ class ConfigParser(iniparser.BaseParser): parser.parse() except iniparser.ParseError as pe: raise ConfigFileParseError(pe.filename, str(pe)) - except IOError as err: + except OSError as err: if err.errno == errno.ENOENT: namespace._file_not_found(config_file) return @@ -1892,8 +1892,7 @@ class _Namespace(argparse.Namespace): def _sections(self): for sections in self._parsed: - for section in sections: - yield section + yield from sections class _CachedArgumentParser(argparse.ArgumentParser): @@ -1908,7 +1907,7 @@ class _CachedArgumentParser(argparse.ArgumentParser): """ def __init__(self, prog=None, usage=None, **kwargs): - super(_CachedArgumentParser, self).__init__(prog, usage, **kwargs) + super().__init__(prog, usage, **kwargs) self._args_cache = {} def add_parser_argument(self, container, *args, **kwargs): @@ -1944,15 +1943,15 @@ class _CachedArgumentParser(argparse.ArgumentParser): def parse_args(self, args=None, namespace=None): self.initialize_parser_arguments() - return super(_CachedArgumentParser, self).parse_args(args, namespace) + return super().parse_args(args, namespace) def print_help(self, file=None): self.initialize_parser_arguments() - super(_CachedArgumentParser, self).print_help(file) + super().print_help(file) def print_usage(self, file=None): self.initialize_parser_arguments() - super(_CachedArgumentParser, self).print_usage(file) + super().print_usage(file) class ConfigOpts(abc.Mapping): @@ -2000,7 +1999,7 @@ class ConfigOpts(abc.Mapping): self._oparser = None self._namespace = None self._mutable_ns = None - self._mutate_hooks = set([]) + self._mutate_hooks = set() self.__cache = {} self.__drivers_cache = {} self._config_opts = [] @@ -2305,7 +2304,7 @@ class ConfigOpts(abc.Mapping): b_opts_sub += f"[{k}]='{sub}' " b_map = ' '.join([f"[{k}]={v}" for k, v in maps.items()]) b_multi = ' '.join([f"[{k}]=true" for k in multi]) - with open(template, "r") as input: + with open(template) as input: output = input.read().format(scriptname=self.prog, opts=b_opts, opts_sub=b_opts_sub, @@ -2372,7 +2371,7 @@ class ConfigOpts(abc.Mapping): desc = descr[k+'_'+ik] if descr[k+'_'+ik] else '' c_opts += f"'[{desc}]' \\\n" c_opts += f"\n{t*4};;\n" - with open(template, "r") as input: + with open(template) as input: output = input.read().format(scriptname=p, opts=z_opts, commands_list=c_list, @@ -2449,9 +2448,8 @@ class ConfigOpts(abc.Mapping): def __iter__(self): """Iterate over all registered opt and group names.""" - for key in itertools.chain(list(self._opts.keys()), - list(self._groups.keys())): - yield key + yield from itertools.chain(list(self._opts.keys()), + list(self._groups.keys())) def __len__(self): """Return the number of options and option groups.""" @@ -2824,7 +2822,7 @@ class ConfigOpts(abc.Mapping): for opt_name in sorted(self._groups[group_name]._opts): opt = self._get_opt_info(opt_name, group_name)['opt'] logger.log(lvl, "%-30s = %s", - "%s.%s" % (group_name, opt_name), + "{}.{}".format(group_name, opt_name), _sanitize(opt, getattr(group_attr, opt_name))) logger.log(lvl, "*" * 80) @@ -2941,8 +2939,8 @@ class ConfigOpts(abc.Mapping): if env_val[0] != sources._NoValue: return (convert(env_val[0]), env_val[1]) except ValueError as ve: - message = "Value for option %s from %s is not valid: %s" % ( - opt.name, alt_loc, str(ve)) + message = ("Value for option {} from {} is not valid: {}" + .format(opt.name, alt_loc, str(ve))) # Preserve backwards compatibility for file-based value # errors. if alt_loc.location == Locations.user: @@ -3194,8 +3192,9 @@ class ConfigOpts(abc.Mapping): try: self._convert_value(value, opt) except ValueError: - sys.stderr.write("argument --%s: Invalid %s value: %s\n" % ( - opt.dest, repr(opt.type), value)) + sys.stderr.write( + "argument --{}: Invalid {} value: {}\n".format( + opt.dest, repr(opt.type), value)) raise SystemExit(1) def _reload_config_files(self): @@ -3330,7 +3329,7 @@ class ConfigOpts(abc.Mapping): Returns a sorted list of all section names found in the configuration files, whether declared beforehand or not. """ - s = set([]) + s = set() if self._mutable_ns: s |= set(self._mutable_ns._sections()) if self._namespace: @@ -3387,8 +3386,7 @@ class ConfigOpts(abc.Mapping): def __iter__(self): """Iterate over all registered opt and group names.""" - for key in self._group._opts.keys(): - yield key + yield from self._group._opts.keys() def __len__(self): """Return the number of options and option groups.""" diff --git a/oslo_config/fixture.py b/oslo_config/fixture.py index 2cb4662c..6a555fa8 100644 --- a/oslo_config/fixture.py +++ b/oslo_config/fixture.py @@ -31,7 +31,7 @@ class Config(fixtures.Fixture): self.conf = conf def setUp(self): - super(Config, self).setUp() + super().setUp() # NOTE(morganfainberg): unregister must be added to cleanup before # reset is because cleanup works in reverse order of registered items, # and a reset must occur before unregistering options can occur. diff --git a/oslo_config/generator.py b/oslo_config/generator.py index 8f8f85e5..f5af92a1 100644 --- a/oslo_config/generator.py +++ b/oslo_config/generator.py @@ -284,7 +284,7 @@ class _OptFormatter: else: opt_help = opt.help - help_text = '%s%s (%s)' % (opt_prefix, opt_help, opt_type) + help_text = '{}{} ({})'.format(opt_prefix, opt_help, opt_type) else: help_text = '(%s)' % opt_type lines = self._format_help(help_text) @@ -298,7 +298,7 @@ class _OptFormatter: if getattr(opt.type, 'choices', None): lines.append('# Possible values:\n') for choice in opt.type.choices: - help_text = '%s - %s' % ( + help_text = '{} - {}'.format( self._get_choice_text(choice), opt.type.choices[choice] or '') lines.extend(self._format_help(help_text)) @@ -379,9 +379,9 @@ class _OptFormatter: if default_str: default_str = ' ' + default_str.replace('\n', '\n# ') if self.minimal: - lines.append('%s =%s\n' % (opt.dest, default_str)) + lines.append('{} ={}\n'.format(opt.dest, default_str)) else: - lines.append('#%s =%s\n' % (opt.dest, default_str)) + lines.append('#{} ={}\n'.format(opt.dest, default_str)) self.writelines(lines) @@ -578,7 +578,7 @@ def _output_opts(f, group, group_data): except Exception as err: f.write('# Warning: Failed to format sample for %s\n' % (opt.dest,)) - f.write('# %s\n' % (err,)) + f.write('# {}\n'.format(err)) def _get_groups(conf_ns): diff --git a/oslo_config/sphinxconfiggen.py b/oslo_config/sphinxconfiggen.py index 616e8573..3ff5028f 100644 --- a/oslo_config/sphinxconfiggen.py +++ b/oslo_config/sphinxconfiggen.py @@ -56,7 +56,7 @@ def _get_default_basename(config_file): def _generate_sample(app, config_file, base_name): def info(msg): - LOG.info('[%s] %s' % (__name__, msg)) + LOG.info('[{}] {}'.format(__name__, msg)) # If we are given a file that isn't an absolute path, look for it # in the source directory if it doesn't exist. diff --git a/oslo_config/sphinxext.py b/oslo_config/sphinxext.py index 6aadf73c..524486f5 100644 --- a/oslo_config/sphinxext.py +++ b/oslo_config/sphinxext.py @@ -60,8 +60,8 @@ def _indent(text, n=2): def _make_anchor_target(group_name, option_name): # We need to ensure this is unique across entire documentation # http://www.sphinx-doc.org/en/stable/markup/inline.html#ref-role - target = '%s.%s' % (cfg._normalize_group_name(group_name), - option_name.lower()) + target = '{}.{}'.format(cfg._normalize_group_name(group_name), + option_name.lower()) return target @@ -220,12 +220,10 @@ def _format_group_opts(namespace, group_name, group_obj, opt_list): group_name = group_name or 'DEFAULT' LOG.debug('%s %s', namespace, group_name) - for line in _format_group(namespace, group_name, group_obj): - yield line + yield from _format_group(namespace, group_name, group_obj) for opt in opt_list: - for line in _format_opt(opt, group_name): - yield line + yield from _format_opt(opt, group_name) def _format_option_help(namespaces, split_namespaces): @@ -252,8 +250,7 @@ def _format_option_help(namespaces, split_namespaces): group_obj=group, opt_list=opts, ) - for line in lines: - yield line + yield from lines else: # Merge the options from different namespaces that belong to # the same group together and format them without the @@ -278,8 +275,7 @@ def _format_option_help(namespaces, split_namespaces): group_obj=group_objs.get(group_name), opt_list=group_opts, ) - for line in lines: - yield line + yield from lines class ShowOptionsDirective(rst.Directive): @@ -337,7 +333,7 @@ class ConfigGroupXRefRole(XRefRole): "Handles :oslo.config:group: roles pointing to configuration groups." def __init__(self): - super(ConfigGroupXRefRole, self).__init__( + super().__init__( warn_dangling=True, ) @@ -350,7 +346,7 @@ class ConfigOptXRefRole(XRefRole): "Handles :oslo.config:option: roles pointing to configuration options." def __init__(self): - super(ConfigOptXRefRole, self).__init__( + super().__init__( warn_dangling=True, ) @@ -400,7 +396,7 @@ class ConfigGroup(rst.Directive): result.append(text, source_name) if namespace: - title = '%s: %s' % (namespace, group_name) + title = '{}: {}'.format(namespace, group_name) else: title = group_name diff --git a/oslo_config/tests/test_cfg.py b/oslo_config/tests/test_cfg.py index 383b70f1..d1e4f25e 100644 --- a/oslo_config/tests/test_cfg.py +++ b/oslo_config/tests/test_cfg.py @@ -108,7 +108,7 @@ class BaseTestCase(base.BaseTestCase): validate_default_values=True) def setUp(self): - super(BaseTestCase, self).setUp() + super().setUp() self.useFixture(fixtures.NestedTempfile()) self.conf = self.TestConfigOpts() @@ -1130,7 +1130,7 @@ def _fake_deprecated_feature(logger, msg, *args, **kwargs): class ConfigFileOptsTestCase(BaseTestCase): def setUp(self): - super(ConfigFileOptsTestCase, self).setUp() + super().setUp() self.logger = self.useFixture( fixtures.FakeLogger( format='%(message)s', @@ -2284,7 +2284,7 @@ class ConfigFileReloadTestCase(BaseTestCase): class ConfigFileMutateTestCase(BaseTestCase): def setUp(self): - super(ConfigFileMutateTestCase, self).setUp() + super().setUp() self.my_group = cfg.OptGroup('group', 'group options') self.conf.register_group(self.my_group) @@ -4013,7 +4013,7 @@ class OptDumpingTestCase(BaseTestCase): self.logged.append(fmt % args) def setUp(self): - super(OptDumpingTestCase, self).setUp() + super().setUp() self._args = ['--foo', 'this', '--blaa-bar', 'that', '--blaa-key', 'admin', '--passwd', 'hush'] @@ -4135,7 +4135,7 @@ class ConfigParserTestCase(BaseTestCase): class NamespaceTestCase(BaseTestCase): def setUp(self): - super(NamespaceTestCase, self).setUp() + super().setUp() self.ns = cfg._Namespace(self.conf) def read(self, *texts): @@ -5002,7 +5002,7 @@ class SectionsTestCase(BaseTestCase): class DeprecationWarningTestBase(BaseTestCase): def setUp(self): - super(DeprecationWarningTestBase, self).setUp() + super().setUp() self.log_fixture = self.useFixture(fixtures.FakeLogger()) self._parser_class = cfg.ConfigParser @@ -5162,7 +5162,7 @@ class DeprecationWarningTestsNoOsloLog(DeprecationWarningTests): log_prefix = '' def setUp(self): - super(DeprecationWarningTestsNoOsloLog, self).setUp() + super().setUp() # NOTE(bnemec): For some reason if I apply this as a class decorator # it ends up applying to the parent class too and breaks those tests. self.useFixture(fixtures.MockPatchObject(cfg, 'oslo_log', None)) diff --git a/oslo_config/tests/test_generator.py b/oslo_config/tests/test_generator.py index 40704c68..54fb3101 100644 --- a/oslo_config/tests/test_generator.py +++ b/oslo_config/tests/test_generator.py @@ -952,7 +952,7 @@ class GeneratorTestCase(base.BaseTestCase): cls.output_file_scenarios) def setUp(self): - super(GeneratorTestCase, self).setUp() + super().setUp() self.conf = cfg.ConfigOpts() self.config_fixture = config_fixture.Config(self.conf) @@ -1007,7 +1007,7 @@ class GeneratorTestCase(base.BaseTestCase): if self.stdout: self.assertEqual(self.expected, stdout.getvalue()) else: - with open(output_file, 'r') as f: + with open(output_file) as f: actual = f.read() self.assertEqual(self.expected, actual) @@ -1021,7 +1021,7 @@ class GeneratorTestCase(base.BaseTestCase): class GeneratorFileHandlingTestCase(base.BaseTestCase): def setUp(self): - super(GeneratorFileHandlingTestCase, self).setUp() + super().setUp() self.conf = cfg.ConfigOpts() self.config_fixture = config_fixture.Config(self.conf) @@ -1056,7 +1056,7 @@ class GeneratorFileHandlingTestCase(base.BaseTestCase): class DriverOptionTestCase(base.BaseTestCase): def setUp(self): - super(DriverOptionTestCase, self).setUp() + super().setUp() self.conf = cfg.ConfigOpts() self.config_fixture = config_fixture.Config(self.conf) @@ -1390,7 +1390,7 @@ class MachineReadableGeneratorTestCase(base.BaseTestCase): ] def setUp(self): - super(MachineReadableGeneratorTestCase, self).setUp() + super().setUp() self.conf = cfg.ConfigOpts() self.config_fixture = config_fixture.Config(self.conf) @@ -1550,7 +1550,7 @@ class GeneratorAdditionalTestCase(base.BaseTestCase): generator._output_opts(formatter, 'DEFAULT', groups.pop('DEFAULT')) expected = '''[DEFAULT] ''' - with open(tmp_file, 'r') as f: + with open(tmp_file) as f: actual = f.read() self.assertEqual(expected, actual) @@ -1573,7 +1573,7 @@ class GeneratorAdditionalTestCase(base.BaseTestCase): # foo option (string value) #foo = fred ''' - with open(tmp_file, 'r') as f: + with open(tmp_file) as f: actual = f.read() self.assertEqual(expected, actual) @@ -1593,8 +1593,8 @@ class GeneratorAdditionalTestCase(base.BaseTestCase): # # a list (list value) -#list_opt = %(default)s -''' % {'default': default} +#list_opt = {default} +'''.format(default=default) generator._output_opts(formatter, 'alpha', groups.pop('alpha')) f.close() content = open(tmp_file).read() @@ -1733,7 +1733,7 @@ bar = # bars foo (string value) bars = ''' - with open(tmp_file, 'r') as f: + with open(tmp_file) as f: actual = f.read() self.assertEqual(expected, actual) @@ -1795,7 +1795,7 @@ messages!""")] # messages! (string value) #bar = ''' - with open(tmp_file, 'r') as f: + with open(tmp_file) as f: actual = f.read() self.assertEqual(expected, actual) @@ -1841,7 +1841,7 @@ class AdvancedOptionsTestCase(base.BaseTestCase): # effect on stability and/or performance. #bars = true ''' - with open(tmp_file, 'r') as f: + with open(tmp_file) as f: actual = f.read() self.assertEqual(expected, actual) diff --git a/oslo_config/tests/test_get_location.py b/oslo_config/tests/test_get_location.py index d06271ae..a1b496b8 100644 --- a/oslo_config/tests/test_get_location.py +++ b/oslo_config/tests/test_get_location.py @@ -10,7 +10,6 @@ # License for the specific language governing permissions and limitations # under the License. -import io import tempfile import textwrap @@ -50,7 +49,7 @@ class LocationTestCase(base.BaseTestCase): class GetLocationTestCase(base.BaseTestCase): def setUp(self): - super(GetLocationTestCase, self).setUp() + super().setUp() def _clear(): cfg._show_caller_details = False @@ -136,7 +135,7 @@ class GetLocationTestCase(base.BaseTestCase): def _write_opt_to_tmp_file(self, group, option, value): filename = tempfile.mktemp() - with io.open(filename, 'w', encoding='utf-8') as f: + with open(filename, 'w', encoding='utf-8') as f: f.write(textwrap.dedent(''' [{group}] {option} = {value} diff --git a/oslo_config/tests/test_sources.py b/oslo_config/tests/test_sources.py index 7c1e8580..90eeca52 100644 --- a/oslo_config/tests/test_sources.py +++ b/oslo_config/tests/test_sources.py @@ -33,7 +33,7 @@ class TestProcessingSources(base.BaseTestCase): # is when the 'config_source' option is processed. def setUp(self): - super(TestProcessingSources, self).setUp() + super().setUp() self.conf = cfg.ConfigOpts() self.conf_fixture = self.useFixture(fixture.Config(self.conf)) @@ -85,7 +85,7 @@ class TestLoading(base.BaseTestCase): # ConfigOpts setup is done in __call__(). def setUp(self): - super(TestLoading, self).setUp() + super().setUp() self.conf = cfg.ConfigOpts() self.conf_fixture = self.useFixture(fixture.Config(self.conf)) @@ -117,7 +117,7 @@ class TestLoading(base.BaseTestCase): class TestEnvironmentConfigurationSource(base.BaseTestCase): def setUp(self): - super(TestEnvironmentConfigurationSource, self).setUp() + super().setUp() self.conf = cfg.ConfigOpts() self.conf_fixture = self.useFixture(fixture.Config(self.conf)) self.conf.register_opt(cfg.StrOpt('bar'), 'foo') @@ -258,7 +258,7 @@ def opts_to_ini(uri, *args, **kwargs): class URISourceTestCase(base.BaseTestCase): def setUp(self): - super(URISourceTestCase, self).setUp() + super().setUp() self.conf = cfg.ConfigOpts() self.conf_fixture = self.useFixture(fixture.Config(self.conf)) diff --git a/oslo_config/tests/test_types.py b/oslo_config/tests/test_types.py index 7ef3439f..f8b7bba0 100644 --- a/oslo_config/tests/test_types.py +++ b/oslo_config/tests/test_types.py @@ -22,14 +22,14 @@ class ConfigTypeTests(unittest.TestCase): def test_none_concrete_class(self): class MyString(types.ConfigType): def __init__(self, type_name='mystring value'): - super(MyString, self).__init__(type_name=type_name) + super().__init__(type_name=type_name) self.assertRaises(TypeError, MyString) def test_concrete_class(self): class MyString(types.ConfigType): def __init__(self, type_name='mystring value'): - super(MyString, self).__init__(type_name=type_name) + super().__init__(type_name=type_name) def _formatter(self, value): return value @@ -39,7 +39,7 @@ class ConfigTypeTests(unittest.TestCase): class TypeTestHelper: def setUp(self): - super(TypeTestHelper, self).setUp() + super().setUp() self.type_instance = self.type def assertConvertedValue(self, s, expected): diff --git a/oslo_config/tests/test_validator.py b/oslo_config/tests/test_validator.py index 383340f2..7786c75b 100644 --- a/oslo_config/tests/test_validator.py +++ b/oslo_config/tests/test_validator.py @@ -83,7 +83,7 @@ opt = value class TestValidator(base.BaseTestCase): def setUp(self): - super(TestValidator, self).setUp() + super().setUp() self.conf = cfg.ConfigOpts() self.conf_fixture = self.useFixture(fixture.Config(self.conf)) validator._register_cli_opts(self.conf) diff --git a/oslo_config/types.py b/oslo_config/types.py index 9fef13af..d9835ca6 100644 --- a/oslo_config/types.py +++ b/oslo_config/types.py @@ -108,7 +108,7 @@ class String(ConfigType): def __init__(self, choices=None, quotes=False, regex=None, ignore_case=False, max_length=None, type_name='string value'): - super(String, self).__init__(type_name=type_name) + super().__init__(type_name=type_name) if choices and regex: raise ValueError("'choices' and 'regex' cannot both be specified") @@ -165,7 +165,7 @@ class String(ConfigType): return value raise ValueError( - 'Valid values are [%s], but found %s' % ( + 'Valid values are [{}], but found {}'.format( ', '.join([str(v) for v in self.choices]), repr(value))) @@ -184,8 +184,8 @@ class String(ConfigType): (self.__class__ == other.__class__) and (self.quotes == other.quotes) and (self.regex == other.regex) and - (set([x for x in self.choices or []]) == - set([x for x in other.choices or []]) if + ({x for x in self.choices or []} == + {x for x in other.choices or []} if self.choices and other.choices else self.choices == other.choices) ) @@ -198,7 +198,7 @@ class MultiString(String): """Multi-valued string.""" def __init__(self, type_name='multi valued'): - super(MultiString, self).__init__(type_name=type_name) + super().__init__(type_name=type_name) NONE_DEFAULT = [''] @@ -235,7 +235,7 @@ class Boolean(ConfigType): FALSE_VALUES = ['false', '0', 'off', 'no'] def __init__(self, type_name='boolean value'): - super(Boolean, self).__init__(type_name=type_name) + super().__init__(type_name=type_name) def __call__(self, value): if isinstance(value, bool): @@ -279,7 +279,7 @@ class Number(ConfigType): def __init__(self, num_type, type_name, min=None, max=None, choices=None): - super(Number, self).__init__(type_name=type_name) + super().__init__(type_name=type_name) if min is not None and max is not None and max < min: raise ValueError('Max value is less than min value') @@ -319,8 +319,9 @@ class Number(ConfigType): self.max) else: if value not in self.choices: - raise ValueError('Valid values are %r, but found %g' % ( - self.choices, value)) + raise ValueError( + 'Valid values are {!r}, but found {:g}'.format( + self.choices, value)) return value def __repr__(self): @@ -342,8 +343,8 @@ class Number(ConfigType): (self.__class__ == other.__class__) and (self.min == other.min) and (self.max == other.max) and - (set([x for x in self.choices or []]) == - set([x for x in other.choices or []]) if + ({x for x in self.choices or []} == + {x for x in other.choices or []} if self.choices and other.choices else self.choices == other.choices) ) @@ -385,8 +386,8 @@ class Integer(Number): def __init__(self, min=None, max=None, type_name='integer value', choices=None): - super(Integer, self).__init__(int, type_name, min=min, max=max, - choices=choices) + super().__init__(int, type_name, min=min, max=max, + choices=choices) class Float(Number): @@ -408,7 +409,7 @@ class Float(Number): """ def __init__(self, min=None, max=None, type_name='floating point value'): - super(Float, self).__init__(float, type_name, min=min, max=max) + super().__init__(float, type_name, min=min, max=max) class Port(Integer): @@ -443,8 +444,8 @@ class Port(Integer): raise ValueError('Max value cannot be more than %(max)d' % {'max': self.PORT_MAX}) - super(Port, self).__init__(min=min, max=max, type_name=type_name, - choices=choices) + super().__init__(min=min, max=max, type_name=type_name, + choices=choices) class List(ConfigType): @@ -470,7 +471,7 @@ class List(ConfigType): """ def __init__(self, item_type=None, bounds=False, type_name='list value'): - super(List, self).__init__(type_name=type_name) + super().__init__(type_name=type_name) if item_type is None: item_type = String() @@ -559,7 +560,7 @@ class Range(ConfigType): def __init__(self, min=None, max=None, inclusive=True, type_name='range value'): - super(Range, self).__init__(type_name) + super().__init__(type_name) self.min = min self.max = max self.inclusive = inclusive @@ -567,7 +568,7 @@ class Range(ConfigType): def __call__(self, value): value = str(value) num = "0|-?[1-9][0-9]*" - m = re.match("^(%s)(?:-(%s))?$" % (num, num), value) + m = re.match("^({})(?:-({}))?$".format(num, num), value) if not m: raise ValueError('Invalid Range: %s' % value) left = int(m.group(1)) @@ -620,7 +621,7 @@ class Dict(ConfigType): def __init__(self, value_type=None, bounds=False, type_name='dict value', key_value_separator=':'): - super(Dict, self).__init__(type_name=type_name) + super().__init__(type_name=type_name) if value_type is None: value_type = String() @@ -721,7 +722,7 @@ class IPAddress(ConfigType): """ def __init__(self, version=None, type_name='IP address value'): - super(IPAddress, self).__init__(type_name=type_name) + super().__init__(type_name=type_name) version_checkers = { None: self._check_both_versions, 4: self._check_ipv4, @@ -775,7 +776,7 @@ class Hostname(ConfigType): HOSTNAME_REGEX = '(?!-)[A-Z0-9-]{1,63}(?