diff --git a/confuse/core.py b/confuse/core.py index 5015705..c63b1a9 100644 --- a/confuse/core.py +++ b/confuse/core.py @@ -24,7 +24,7 @@ from . import util from . import templates from . import yaml_util -from .sources import ConfigSource +from .sources import ConfigSource, YamlSource from .exceptions import ConfigTypeError, NotFoundError, ConfigError CONFIG_FILENAME = 'config.yaml' @@ -570,10 +570,7 @@ def _add_user_source(self): exists. """ filename = self.user_config_path() - if os.path.isfile(filename): - yaml_data = yaml_util.load_yaml(filename, loader=self.loader) \ - or {} - self.add(ConfigSource(yaml_data, filename)) + self.add(YamlSource(filename, loader=self.loader, optional=True)) def _add_default_source(self): """Add the package's default configuration settings. This looks @@ -583,12 +580,8 @@ def _add_default_source(self): if self.modname: if self._package_path: filename = os.path.join(self._package_path, DEFAULT_FILENAME) - if os.path.isfile(filename): - yaml_data = yaml_util.load_yaml( - filename, - loader=self.loader, - ) - self.add(ConfigSource(yaml_data, filename, True)) + self.add(YamlSource(filename, loader=self.loader, + optional=True, default=True)) def read(self, user=True, defaults=True): """Find and read the files for this configuration and set them @@ -641,9 +634,7 @@ def set_file(self, filename): """Parses the file as YAML and inserts it into the configuration sources with highest priority. """ - filename = os.path.abspath(filename) - yaml_data = yaml_util.load_yaml(filename, loader=self.loader) - self.set(ConfigSource(yaml_data, filename)) + self.set(YamlSource(filename, loader=self.loader)) def dump(self, full=True, redact=False): """Dump the Configuration object to a YAML file. diff --git a/confuse/sources.py b/confuse/sources.py index bba603d..82dc0fd 100644 --- a/confuse/sources.py +++ b/confuse/sources.py @@ -1,8 +1,8 @@ from __future__ import division, absolute_import, print_function from .util import BASESTRING - -__all__ = ['ConfigSource'] +from . import yaml_util +import os class ConfigSource(dict): @@ -36,3 +36,24 @@ def of(cls, value): return ConfigSource(value) else: raise TypeError(u'source value must be a dict') + + +class YamlSource(ConfigSource): + """A configuration data source that reads from a YAML file. + """ + + def __init__(self, filename=None, default=False, + optional=False, loader=yaml_util.Loader): + """Create a YAML data source by reading data from a file. + + May raise a `ConfigReadError`. However, if `optional` is + enabled, this exception will not be raised in the case when the + file does not exist---instead, the source will be silently + empty. + """ + filename = os.path.abspath(filename) + if optional and not os.path.isfile(filename): + value = {} + else: + value = yaml_util.load_yaml(filename, loader=loader) or {} + super(YamlSource, self).__init__(value, filename, default)