From 02518b17df20151a47dda077e3c9446f96403378 Mon Sep 17 00:00:00 2001 From: Thomas Adamcik Date: Sat, 13 Apr 2013 00:38:22 +0200 Subject: [PATCH] config: Refactor to internal API that is closer to end goal for load and validate --- mopidy/config/__init__.py | 46 +++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/mopidy/config/__init__.py b/mopidy/config/__init__.py index 715027cc..a4e7a364 100644 --- a/mopidy/config/__init__.py +++ b/mopidy/config/__init__.py @@ -55,29 +55,31 @@ config_schemas['proxy']['password'] = String(optional=True, secret=True) #config_schemas['audio.outputs'] = config.AudioOutputConfigSchema() -# TODO: update API to load(files, defaults, overrides) this should not need to -# know about extensions def load(files, overrides, extensions=None): + defaults = [default_config] + if extensions: + defaults.extend(e.get_default_config() for e in extensions) + return _load(files, defaults, extensions) + + +# TODO: replace load() with this version of API. +def _load(files, defaults, overrides): parser = configparser.RawConfigParser() files = [path.expand_path(f) for f in files] sources = ['builtin-defaults'] + files + ['command-line'] logger.info('Loading config from: %s', ', '.join(sources)) - # Read default core config - parser.readfp(io.StringIO(default_config)) - - # Read default extension config - for extension in extensions or []: - parser.readfp(io.StringIO(extension.get_default_config())) + for default in defaults: + parser.readfp(io.StringIO(default)) # Load config from a series of config files for filename in files: # TODO: if this is the initial load of logging config we might not have # a logger at this point, we might want to handle this better. try: - filehandle = codecs.open(filename, encoding='utf-8') - parser.readfp(filehandle) + with codecs.open(filename, encoding='utf-8') as filehandle: + parser.readfp(filehandle) except IOError: logger.debug('Config file %s not found; skipping', filename) continue @@ -89,39 +91,41 @@ def load(files, overrides, extensions=None): for section in parser.sections(): raw_config[section] = dict(parser.items(section)) - # TODO: move out of file loading code? for section, key, value in overrides or []: raw_config.setdefault(section, {})[key] = value return raw_config -# TODO: switch API to validate(raw_config, schemas) this should not need to -# know about extensions def validate(raw_config, schemas, extensions=None): # Collect config schemas to validate against sections_and_schemas = schemas.items() for extension in extensions or []: sections_and_schemas.append( (extension.ext_name, extension.get_config_schema())) + return _validate(raw_config, sections_and_schemas) + +# TODO: replace validate() with this version of API. +def _validate(raw_config, schemas): # Get validated config config = {} errors = {} - for section_name, schema in sections_and_schemas: - if section_name not in raw_config: - errors[section_name] = {section_name: 'section not found'} + for name, schema in schemas: + if name not in raw_config: + errors[name] = {name: 'section not found'} try: - items = raw_config[section_name].items() - config[section_name] = schema.convert(items) + items = raw_config[name].items() + config[name] = schema.convert(items) + # TODO: convert to ConfigSchemaError except exceptions.ConfigError as error: - errors[section_name] = error + errors[name] = error if errors: # TODO: raise error instead. #raise exceptions.ConfigError(errors) - for section_name, error in errors.items(): - logger.error('[%s] config errors:', section_name) + for name, error in errors.items(): + logger.error('[%s] config errors:', name) for key in error: logger.error('%s %s', key, error[key]) sys.exit(1)