Mercurial > hgrepos > Python > libs > ConfigMix
comparison configmix/__init__.py @ 139:c87b0dc54e1d
Allow custom configuration filename extensions and custom loaders that can handle custom configuration file syntax styles
| author | Franz Glasner <hg@dom66.de> |
|---|---|
| date | Fri, 06 Apr 2018 22:28:45 +0200 |
| parents | b883f4ef1967 |
| children | 647782859ae1 |
comparison
equal
deleted
inserted
replaced
| 138:b883f4ef1967 | 139:c87b0dc54e1d |
|---|---|
| 21 import copy | 21 import copy |
| 22 | 22 |
| 23 from .config import Configuration | 23 from .config import Configuration |
| 24 | 24 |
| 25 | 25 |
| 26 __all__ = ["load", "safe_load", "Configuration"] | 26 __all__ = ["load", "safe_load", |
| 27 "set_loader", "default_loaders", | |
| 28 "Configuration"] | |
| 27 | 29 |
| 28 | 30 |
| 29 def load(*files): | 31 def load(*files): |
| 30 """Load the given configuration files, merge them in the given order | 32 """Load the given configuration files, merge them in the given order |
| 31 and return the resulting configuration dictionary. | 33 and return the resulting configuration dictionary. |
| 77 def _load_ini(filename): | 79 def _load_ini(filename): |
| 78 from . import ini | 80 from . import ini |
| 79 return ini.load(filename) | 81 return ini.load(filename) |
| 80 | 82 |
| 81 | 83 |
| 82 _loaders = { | 84 default_loaders = { |
| 83 ".yml": _load_yaml, | 85 ".yml": _load_yaml, |
| 84 ".yaml": _load_yaml, | 86 ".yaml": _load_yaml, |
| 85 ".json": _load_json, | 87 ".json": _load_json, |
| 86 ".py": _load_py, | 88 ".py": _load_py, |
| 87 ".ini": _load_ini | 89 ".ini": _load_ini |
| 88 } | 90 } |
| 91 """The builtin default associations of extensions with loaders""" | |
| 92 | |
| 93 | |
| 94 DEFAULT_LOADER = object() | |
| 95 """Marker for the default loader for an extension. | |
| 96 | |
| 97 To be used in :func:`set_loader`. | |
| 98 """ | |
| 99 | |
| 100 _loaders = {} | |
| 101 """All configured loader functions""" | |
| 102 | |
| 103 | |
| 104 def clear_loader(): | |
| 105 """Remove all configured loader associations. | |
| 106 | |
| 107 The :data:`default_loaders` are **not** changed. | |
| 108 | |
| 109 """ | |
| 110 _loaders.clear() | |
| 111 | |
| 112 | |
| 113 def set_loader(extension, loader): | |
| 114 """Associate a filename trailer `extension` with a callable `loader` that | |
| 115 will be called when :func:`load` encounters a file argument that ends | |
| 116 with `extension`. | |
| 117 | |
| 118 :param str extension: the extension to associate a loader with | |
| 119 :param callable loader: a callable that accepts a `filename` argument and | |
| 120 returns a parsed configuration from a given file | |
| 121 | |
| 122 If `loader` is :data:`DEFAULT_LOADER` then the default association | |
| 123 from :data:`default_loaders` will be used -- if any. | |
| 124 | |
| 125 """ | |
| 126 if loader is DEFAULT_LOADER: | |
| 127 try: | |
| 128 _loaders[extension] = default_loaders[extension] | |
| 129 except KeyError: | |
| 130 raise ValueError("no DEFAULT loader for extension: %r" % extension) | |
| 131 else: | |
| 132 _loaders[extension] = loader | |
| 89 | 133 |
| 90 | 134 |
| 91 def _load_cfg_from_file(filename): | 135 def _load_cfg_from_file(filename): |
| 92 fnl = filename.lower() | 136 fnl = filename.lower() |
| 93 extensions = list(_loaders.keys()) | 137 extensions = list(_loaders.keys()) |
| 192 if k not in user: | 236 if k not in user: |
| 193 user[k] = copy.deepcopy(v) | 237 user[k] = copy.deepcopy(v) |
| 194 else: | 238 else: |
| 195 user[k] = _safe_merge(user[k], v) | 239 user[k] = _safe_merge(user[k], v) |
| 196 return user | 240 return user |
| 241 | |
| 242 | |
| 243 # | |
| 244 # Init loader defaults | |
| 245 # | |
| 246 for _extension in default_loaders: | |
| 247 set_loader(_extension, DEFAULT_LOADER) |
