Mercurial > hgrepos > Python > libs > ConfigMix
comparison configmix/__init__.py @ 293:6f0bf673d4ff
Provide an optional "strict" flag to the top-level loader to pass it to low-level loaders that understand it.
Currently only the YAML loader understands this flag.
| author | Franz Glasner <f.glasner@feldmann-mg.com> |
|---|---|
| date | Wed, 10 Feb 2021 15:25:55 +0100 |
| parents | aec97edf7945 |
| children | eed16a1ec8f3 |
comparison
equal
deleted
inserted
replaced
| 292:6a044778371a | 293:6f0bf673d4ff |
|---|---|
| 73 last | 73 last |
| 74 | 74 |
| 75 Use this for example to overwrite configuration file | 75 Use this for example to overwrite configuration file |
| 76 settings from commandline arguments. | 76 settings from commandline arguments. |
| 77 :type extras: dict-alike or None | 77 :type extras: dict-alike or None |
| 78 :keyword strict: enable strict parsing mode for parsers that support it | |
| 79 (e.g. to prevent duplicate keys) | |
| 80 :type strict: bool | |
| 78 :returns: the configuration | 81 :returns: the configuration |
| 79 :rtype: ~configmix.config.Configuration | 82 :rtype: ~configmix.config.Configuration |
| 80 | 83 |
| 81 """ | 84 """ |
| 82 defaults = kwargs.get("defaults") | 85 defaults = kwargs.get("defaults") |
| 83 extras = kwargs.get("extras") | 86 extras = kwargs.get("extras") |
| 87 strict = kwargs.get("strict", False) | |
| 84 if defaults is None: | 88 if defaults is None: |
| 85 ex = Configuration() | 89 ex = Configuration() |
| 86 else: | 90 else: |
| 87 ex = merge(None, Configuration(defaults)) | 91 ex = merge(None, Configuration(defaults)) |
| 88 for f in files: | 92 for f in files: |
| 89 if f.startswith(DIR_PREFIX): | 93 if f.startswith(DIR_PREFIX): |
| 90 for f2 in _get_configuration_files_from_dir(f[5:]): | 94 for f2 in _get_configuration_files_from_dir(f[5:]): |
| 91 nx = _load_cfg_from_file(f2, ignore_unknown=True) | 95 nx = _load_cfg_from_file(f2, ignore_unknown=True, strict=strict) |
| 92 if nx is not None: | 96 if nx is not None: |
| 93 ex = merge(nx, ex) | 97 ex = merge(nx, ex) |
| 94 else: | 98 else: |
| 95 nx = _load_cfg_from_file(f) | 99 nx = _load_cfg_from_file(f, strict=strict) |
| 96 if nx is not None: | 100 if nx is not None: |
| 97 ex = merge(nx, ex) | 101 ex = merge(nx, ex) |
| 98 if extras: | 102 if extras: |
| 99 ex = merge(Configuration(extras), ex) | 103 ex = merge(Configuration(extras), ex) |
| 100 return Configuration(ex) | 104 return Configuration(ex) |
| 105 instead of :func:`.merge` | 109 instead of :func:`.merge` |
| 106 | 110 |
| 107 """ | 111 """ |
| 108 defaults = kwargs.get("defaults") | 112 defaults = kwargs.get("defaults") |
| 109 extras = kwargs.get("extras") | 113 extras = kwargs.get("extras") |
| 114 strict = kwargs.get("strict", False) | |
| 110 if defaults is None: | 115 if defaults is None: |
| 111 ex = Configuration() | 116 ex = Configuration() |
| 112 else: | 117 else: |
| 113 ex = safe_merge(None, Configuration(defaults)) | 118 ex = safe_merge(None, Configuration(defaults)) |
| 114 for f in files: | 119 for f in files: |
| 115 if f.startswith(DIR_PREFIX): | 120 if f.startswith(DIR_PREFIX): |
| 116 for f2 in _get_configuration_files_from_dir(f[5:]): | 121 for f2 in _get_configuration_files_from_dir(f[5:]): |
| 117 nx = _load_cfg_from_file(f2, ignore_unknown=True) | 122 nx = _load_cfg_from_file(f2, ignore_unknown=True, strict=strict) |
| 118 if nx is not None: | 123 if nx is not None: |
| 119 ex = safe_merge(nx, ex) | 124 ex = safe_merge(nx, ex) |
| 120 else: | 125 else: |
| 121 nx = _load_cfg_from_file(f) | 126 nx = _load_cfg_from_file(f, strict=strict) |
| 122 if nx is not None: | 127 if nx is not None: |
| 123 ex = safe_merge(nx, ex) | 128 ex = safe_merge(nx, ex) |
| 124 if extras: | 129 if extras: |
| 125 ex = safe_merge(Configuration(extras), ex) | 130 ex = safe_merge(Configuration(extras), ex) |
| 126 return Configuration(ex) | 131 return Configuration(ex) |
| 144 continue | 149 continue |
| 145 files.append(path) | 150 files.append(path) |
| 146 return files | 151 return files |
| 147 | 152 |
| 148 | 153 |
| 149 def _load_yaml(filename): | 154 def _load_yaml(filename, strict=False): |
| 150 from . import yaml | 155 from . import yaml |
| 151 with open(u2fs(filename), "rb") as yf: | 156 with open(u2fs(filename), "rb") as yf: |
| 152 return yaml.safe_load(yf) | 157 return yaml.safe_load(yf, strict=strict) |
| 153 | 158 |
| 154 | 159 |
| 155 def _load_json(filename): | 160 def _load_json(filename, strict=False): |
| 156 from . import json | 161 from . import json |
| 157 return json.load(filename) | 162 return json.load(filename) |
| 158 | 163 |
| 159 | 164 |
| 160 def _load_py(filename): | 165 def _load_py(filename, strict=False): |
| 161 from . import py | 166 from . import py |
| 162 return py.load(filename) | 167 return py.load(filename) |
| 163 | 168 |
| 164 | 169 |
| 165 def _load_ini(filename): | 170 def _load_ini(filename, strict=False): |
| 166 from . import ini | 171 from . import ini |
| 167 return ini.load(filename) | 172 return ini.load(filename) |
| 168 | 173 |
| 169 | 174 |
| 170 def _load_toml(filename): | 175 def _load_toml(filename, strict=False): |
| 171 from . import toml | 176 from . import toml |
| 172 return toml.load(filename) | 177 return toml.load(filename) |
| 173 | 178 |
| 174 | 179 |
| 175 def _load_ignore(filename): | 180 def _load_ignore(filename, strict=False): |
| 176 """A loader that returns `None` just to ignore `filename`""" | 181 """A loader that returns `None` just to ignore `filename`""" |
| 177 return None | 182 return None |
| 178 | 183 |
| 179 | 184 |
| 180 EMACS_MODELINE = re.compile(r"-\*-(.*?)-\*-") | 185 EMACS_MODELINE = re.compile(r"-\*-(.*?)-\*-") |
| 357 break # restart | 362 break # restart |
| 358 else: | 363 else: |
| 359 return # nothing deleted -> done | 364 return # nothing deleted -> done |
| 360 | 365 |
| 361 | 366 |
| 362 def _load_cfg_from_file(filename, ignore_unknown=False): | 367 def _load_cfg_from_file(filename, ignore_unknown=False, strict=False): |
| 363 """Determine the loader for file `filename` and return the loaded | 368 """Determine the loader for file `filename` and return the loaded |
| 364 configuration dict. | 369 configuration dict. |
| 365 | 370 |
| 366 If `ignore_unknown` is `True` then unknown extensions are ignored. | 371 If `ignore_unknown` is `True` then unknown extensions are ignored. |
| 367 Otherwise a :exc:`ValueError` exception is raised. | 372 Otherwise a :exc:`ValueError` exception is raised. |
| 373 if fnmatch.fnmatch(filename, p): | 378 if fnmatch.fnmatch(filename, p): |
| 374 if callable(m): | 379 if callable(m): |
| 375 m = m(filename) | 380 m = m(filename) |
| 376 if m is None: | 381 if m is None: |
| 377 continue | 382 continue |
| 378 return mode_loaders[m](filename) | 383 return mode_loaders[m](filename, strict=strict) |
| 379 else: | 384 else: |
| 380 if ignore_unknown: | 385 if ignore_unknown: |
| 381 return None | 386 return None |
| 382 else: | 387 else: |
| 383 raise ValueError("Unknown configuration file type for filename " | 388 raise ValueError("Unknown configuration file type for filename " |
