Mercurial > hgrepos > Python > libs > ConfigMix
comparison configmix/__init__.py @ 178:eeb3ed104ea1
Begin refactoring the associations between filename extensions and loader functions:
Make is indirect via the file mode.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Thu, 02 May 2019 09:42:28 +0200 |
| parents | 6dde1e344ae8 |
| children | 62db35db8939 |
comparison
equal
deleted
inserted
replaced
| 177:6dde1e344ae8 | 178:eeb3ed104ea1 |
|---|---|
| 114 def _load_ini(filename): | 114 def _load_ini(filename): |
| 115 from . import ini | 115 from . import ini |
| 116 return ini.load(filename) | 116 return ini.load(filename) |
| 117 | 117 |
| 118 | 118 |
| 119 _default_loaders = [ | 119 DEFAULT_MODE_LOADERS = { |
| 120 ("*.yml", _load_yaml), | 120 "python": _load_py, |
| 121 ("*.yaml", _load_yaml), | 121 "yaml": _load_yaml, |
| 122 ("*.json", _load_json), | 122 "conf": _load_ini, |
| 123 ("*.py", _load_py), | 123 "conf-windows": _load_ini, |
| 124 ("*.ini", _load_ini), | 124 "ini": _load_ini, |
| 125 "javascript": _load_json, | |
| 126 "json": _load_json, | |
| 127 } | |
| 128 """Default associations between file modes and loader functions""" | |
| 129 | |
| 130 | |
| 131 DEFAULT_EXTENSIONS = [ | |
| 132 ("*.yml", "yaml"), | |
| 133 ("*.yaml", "yaml"), | |
| 134 ("*.json", "json"), | |
| 135 ("*.py", "python"), | |
| 136 ("*.ini", "conf"), | |
| 125 ] | 137 ] |
| 126 """The builtin default associations of extensions with loaders -- in that | 138 """The builtin default associations of filename extensions with |
| 127 order | 139 file modes -- in that order. |
| 140 | |
| 141 The "mode" part may be a string or a callable with a filename | |
| 142 parameter that returns the mode string for the file or `None` if it | |
| 143 can not determined. | |
| 128 | 144 |
| 129 """ | 145 """ |
| 130 | 146 |
| 131 | 147 |
| 132 DEFAULT_LOADER = object() | 148 DEFAULT_LOADER = object() |
| 146 return loader | 162 return loader |
| 147 else: | 163 else: |
| 148 raise KeyError("No loader for pattern %r" % pattern) | 164 raise KeyError("No loader for pattern %r" % pattern) |
| 149 | 165 |
| 150 | 166 |
| 151 _loaders = [] | 167 _mode_loaders = {} |
| 152 """All configured loader functions""" | 168 """All configured associations between file modes and loader functions. |
| 169 | |
| 170 See :data:`DEFAULT_MODE_LOADERS. | |
| 171 | |
| 172 """ | |
| 173 | |
| 174 _extensions = [] | |
| 175 """All configured assiciations of filename extensions with file modes. | |
| 176 | |
| 177 See :data:`DEFAULT_EXTENSIONS` | |
| 178 | |
| 179 """ | |
| 153 | 180 |
| 154 | 181 |
| 155 def clear_loader(): | 182 def clear_loader(): |
| 156 """Remove all configured loader associations. | 183 """Remove all configured loader associations. |
| 157 | 184 |
| 172 return loader | 199 return loader |
| 173 else: | 200 else: |
| 174 raise KeyError("No loader for pattern %r" % pattern) | 201 raise KeyError("No loader for pattern %r" % pattern) |
| 175 | 202 |
| 176 | 203 |
| 177 def set_loader(fnpattern, loader): | 204 def set_loader(fnpattern, mode): |
| 178 """Associate a :mod:`fnmatch` style pattern `fnpattern` with a | 205 """Associate a :mod:`fnmatch` style pattern `fnpattern` with a file |
| 179 callable `loader` that will be called when :func:`load` encounters | 206 mode `mode` that determines what will be called when :func:`load` |
| 180 a file argument that matches `fnpattern`. | 207 encounters a file argument that matches `fnpattern`. |
| 181 | 208 |
| 182 :param str fnpattern: the :mod:`fnmatch` pattern to associate a loader with | 209 :param str fnpattern: the :mod:`fnmatch` pattern to associate a loader with |
| 183 :param callable loader: a callable that accepts a `filename` argument and | 210 :param callable mode: a mode string or a callable that accepts a |
| 184 returns a parsed configuration from a given file | 211 `filename` argument and returns a file |
| 212 mode for the given file (or `None`) | |
| 185 | 213 |
| 186 This function prepends to the given pattern to the currently defined | 214 This function prepends to the given pattern to the currently defined |
| 187 associations. | 215 associations. |
| 188 | 216 |
| 189 The OS specific case-sensitivity behaviour of | 217 The OS specific case-sensitivity behaviour of |
| 192 | 220 |
| 193 If `loader` is :data:`DEFAULT_LOADER` then the default association | 221 If `loader` is :data:`DEFAULT_LOADER` then the default association |
| 194 from :data:`_default_loaders` will be used -- if any. | 222 from :data:`_default_loaders` will be used -- if any. |
| 195 | 223 |
| 196 """ | 224 """ |
| 197 if loader is DEFAULT_LOADER: | 225 if mode is DEFAULT_LOADER: |
| 198 for _p, _l in _default_loaders: | 226 for p, m in DEFAULT_EXTENSIONS: |
| 199 if _p == fnpattern: | 227 if p == fnpattern: |
| 200 _loaders.insert(0, (fnpattern, _l)) | 228 _extensions.insert(0, (fnpattern, m)) |
| 201 break | 229 break |
| 202 else: | 230 else: |
| 203 raise ValueError("no DEFAULT loader for pattern: %r" % fnpattern) | 231 raise ValueError("no DEFAULT mode for pattern: %r" % fnpattern) |
| 204 else: | 232 else: |
| 205 _loaders.insert(0, (fnpattern, loader)) | 233 _extensions.insert(0, (fnpattern, mode)) |
| 206 | 234 |
| 207 | 235 |
| 208 def _load_cfg_from_file(filename): | 236 def _load_cfg_from_file(filename): |
| 209 for _p, _l in _loaders: | 237 for p, m in _extensions: |
| 210 if fnmatch.fnmatch(filename, _p): | 238 if fnmatch.fnmatch(filename, p): |
| 211 return _l(filename) | 239 if callable(m): |
| 240 m = m(filename) | |
| 241 if m is None: | |
| 242 continue | |
| 243 return _mode_loaders[m](filename) | |
| 212 else: | 244 else: |
| 213 raise ValueError("Unknown configuration file type for filename " | 245 raise ValueError("Unknown configuration file type for filename " |
| 214 "%r" % filename) | 246 "%r" % filename) |
| 215 | 247 |
| 216 | 248 |
| 356 return True | 388 return True |
| 357 return False | 389 return False |
| 358 | 390 |
| 359 | 391 |
| 360 # | 392 # |
| 361 # Init loader defaults | 393 # Init loader defaults: mode->loader and extension->mode |
| 362 # | 394 # |
| 363 for _pattern, _ld in _default_loaders: | 395 _mode_loaders.update(DEFAULT_MODE_LOADERS) |
| 364 set_loader(_pattern, _ld) | 396 for _pattern, _mode in DEFAULT_EXTENSIONS: |
| 397 set_loader(_pattern, _mode) |
