annotate configmix/__init__.py @ 220:2034da70f8fd

Simplify the implementation of configmix.load() and .safe_load(): this also prepare for the coming implementation of a "last" user configuration (analogout to "defaults" as the first configuration).
author Franz Glasner <fzglas.hg@dom66.de>
date Thu, 09 May 2019 09:27:23 +0200
parents b869e792310e
children 6f0f39a9a46f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
53ea2bc254e7 Begin a package to abstract some of the important configuration handling stuff.
Franz Glasner <hg@dom66.de>
parents:
diff changeset
1 # -*- coding: utf-8 -*-
82
218807d7d883 Remove header markup from the Python files and put them into the doc .rst files
Franz Glasner <hg@dom66.de>
parents: 79
diff changeset
2 """A library for helping with configuration files.
4
f76d85ccc5b9 Switch to the "New BSD License"
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 0
diff changeset
3
73
6216c561532a Put a Copyright and License notice into the package's __init__.py
Franz Glasner <hg@dom66.de>
parents: 69
diff changeset
4 :Author: Franz Glasner
156
e2e8d21b4122 Adjust copyright to year 2019
Franz Glasner <fzglas.hg@dom66.de>
parents: 144
diff changeset
5 :Copyright: (c) 2015–2019, Franz Glasner.
73
6216c561532a Put a Copyright and License notice into the package's __init__.py
Franz Glasner <hg@dom66.de>
parents: 69
diff changeset
6 All rights reserved.
78
3a8f712d27df Put copyright and license into the README.txt
Franz Glasner <hg@dom66.de>
parents: 73
diff changeset
7 :License: 3-clause BSD License.
73
6216c561532a Put a Copyright and License notice into the package's __init__.py
Franz Glasner <hg@dom66.de>
parents: 69
diff changeset
8 See LICENSE.txt for details.
174
e2505f524ab9 Use the "@(#)" sigil in the package documentation header
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 173
diff changeset
9 :ID: @(#) $Header$
4
f76d85ccc5b9 Switch to the "New BSD License"
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 0
diff changeset
10
f76d85ccc5b9 Switch to the "New BSD License"
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 0
diff changeset
11 """
0
53ea2bc254e7 Begin a package to abstract some of the important configuration handling stuff.
Franz Glasner <hg@dom66.de>
parents:
diff changeset
12
53ea2bc254e7 Begin a package to abstract some of the important configuration handling stuff.
Franz Glasner <hg@dom66.de>
parents:
diff changeset
13 from __future__ import division, print_function, absolute_import
53ea2bc254e7 Begin a package to abstract some of the important configuration handling stuff.
Franz Glasner <hg@dom66.de>
parents:
diff changeset
14
53ea2bc254e7 Begin a package to abstract some of the important configuration handling stuff.
Franz Glasner <hg@dom66.de>
parents:
diff changeset
15
216
c03c9162f7e6 Prepare next version (planned: 0.7.1.dev1)
Franz Glasner <fzglas.hg@dom66.de>
parents: 214
diff changeset
16 __version__ = "0.7.1.dev1"
0
53ea2bc254e7 Begin a package to abstract some of the important configuration handling stuff.
Franz Glasner <hg@dom66.de>
parents:
diff changeset
17
163
ff03cdf36139 The README.txt should be in the most important parts readable without keyword substitutions.
Franz Glasner <fzglas.hg@dom66.de>
parents: 156
diff changeset
18 __revision__ = "|VCSRevision|"
ff03cdf36139 The README.txt should be in the most important parts readable without keyword substitutions.
Franz Glasner <fzglas.hg@dom66.de>
parents: 156
diff changeset
19 __date__ = "|VCSJustDate|"
52
6c7f90dbce98 Adjusted the Copyright and change the RCS keywords in accordance with "kwarchive"
Franz Glasner <hg@dom66.de>
parents: 45
diff changeset
20
177
6dde1e344ae8 Style: put "__all__" into the meta-variables section as recommended by PEP
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 175
diff changeset
21 __all__ = ["load", "safe_load",
181
7cfdc972af42 Refactor: Renamed public functions to be conform with the new loader search
Franz Glasner <fzglas.hg@dom66.de>
parents: 180
diff changeset
22 "set_assoc", "get_assoc", "clear_assoc",
7cfdc972af42 Refactor: Renamed public functions to be conform with the new loader search
Franz Glasner <fzglas.hg@dom66.de>
parents: 180
diff changeset
23 "get_default_assoc",
180
e87fa5bd68e7 Implemented "try_determine_filemode()" to determine a file-mode from an Emacs-compatible declaration
Franz Glasner <fzglas.hg@dom66.de>
parents: 179
diff changeset
24 "Configuration",
e87fa5bd68e7 Implemented "try_determine_filemode()" to determine a file-mode from an Emacs-compatible declaration
Franz Glasner <fzglas.hg@dom66.de>
parents: 179
diff changeset
25 "try_determine_filemode"]
177
6dde1e344ae8 Style: put "__all__" into the meta-variables section as recommended by PEP
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 175
diff changeset
26
0
53ea2bc254e7 Begin a package to abstract some of the important configuration handling stuff.
Franz Glasner <hg@dom66.de>
parents:
diff changeset
27
171
1ff11462a5c1 The associations from filename extensions to parsers are "fnmatch" style patterns now.
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 170
diff changeset
28 import fnmatch
10
58af59d5af40 A "safe_merge" that makes (shallow) copies instead of directly manipulating given containers
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 9
diff changeset
29 import copy
180
e87fa5bd68e7 Implemented "try_determine_filemode()" to determine a file-mode from an Emacs-compatible declaration
Franz Glasner <fzglas.hg@dom66.de>
parents: 179
diff changeset
30 import io
e87fa5bd68e7 Implemented "try_determine_filemode()" to determine a file-mode from an Emacs-compatible declaration
Franz Glasner <fzglas.hg@dom66.de>
parents: 179
diff changeset
31 import re
10
58af59d5af40 A "safe_merge" that makes (shallow) copies instead of directly manipulating given containers
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 9
diff changeset
32
166
b5ce9a8461bf Use the filesystem encoding explicitely where appropriate.
Franz Glasner <fzglas.hg@dom66.de>
parents: 165
diff changeset
33 from .compat import u, u2fs
22
6a91db2c2469 A convenience function to load and merge a list of configuration files with different styles
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 13
diff changeset
34 from .config import Configuration
10
58af59d5af40 A "safe_merge" that makes (shallow) copies instead of directly manipulating given containers
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 9
diff changeset
35
22
6a91db2c2469 A convenience function to load and merge a list of configuration files with different styles
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 13
diff changeset
36
207
b3b5ed34d180 Handle most flake8 errors and warnings.
Franz Glasner <fzglas.hg@dom66.de>
parents: 206
diff changeset
37 COMMENTS = [
b3b5ed34d180 Handle most flake8 errors and warnings.
Franz Glasner <fzglas.hg@dom66.de>
parents: 206
diff changeset
38 u("__comment"),
b3b5ed34d180 Handle most flake8 errors and warnings.
Franz Glasner <fzglas.hg@dom66.de>
parents: 206
diff changeset
39 u("__doc"),
144
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
40 ]
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
41 """Prefixes for comment configuration keys that are to be handled as
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
42 comments
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
43
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
44 """
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
45
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
46
172
8138d56d7cd3 ".load" and ".safe_load" get a keyword parameter "defaults" that allows the provision of a configuration dictionary with default settings
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 171
diff changeset
47 def load(*files, **kwargs):
22
6a91db2c2469 A convenience function to load and merge a list of configuration files with different styles
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 13
diff changeset
48 """Load the given configuration files, merge them in the given order
108
2196362c0467 Enhance documentation of "configmix.load()"
Franz Glasner <hg@dom66.de>
parents: 107
diff changeset
49 and return the resulting configuration dictionary.
2196362c0467 Enhance documentation of "configmix.load()"
Franz Glasner <hg@dom66.de>
parents: 107
diff changeset
50
2196362c0467 Enhance documentation of "configmix.load()"
Franz Glasner <hg@dom66.de>
parents: 107
diff changeset
51 :param files: the filenames of the configuration files to read and merge
173
b3ba2b0265b5 Docu: Explicitely tag "defaults" as keyword argument
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 172
diff changeset
52 :keyword defaults: optional configuration dictionary with some default
b3ba2b0265b5 Docu: Explicitely tag "defaults" as keyword argument
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 172
diff changeset
53 settings where the settings from `files` are merged
b3ba2b0265b5 Docu: Explicitely tag "defaults" as keyword argument
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 172
diff changeset
54 into
214
a35b0ca8b81f FIX: Docu: Sphinx markup
Franz Glasner <fzglas.hg@dom66.de>
parents: 211
diff changeset
55 :type defaults: dict-alike or None
108
2196362c0467 Enhance documentation of "configmix.load()"
Franz Glasner <hg@dom66.de>
parents: 107
diff changeset
56 :returns: the configuration
2196362c0467 Enhance documentation of "configmix.load()"
Franz Glasner <hg@dom66.de>
parents: 107
diff changeset
57 :rtype: ~configmix.config.Configuration
22
6a91db2c2469 A convenience function to load and merge a list of configuration files with different styles
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 13
diff changeset
58
6a91db2c2469 A convenience function to load and merge a list of configuration files with different styles
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 13
diff changeset
59 """
172
8138d56d7cd3 ".load" and ".safe_load" get a keyword parameter "defaults" that allows the provision of a configuration dictionary with default settings
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 171
diff changeset
60 defaults = kwargs.get("defaults")
217
b869e792310e FIX: Extra merged and unsafe merges in configmix.safe_load
Franz Glasner <fzglas.hg@dom66.de>
parents: 216
diff changeset
61 if defaults is None:
220
2034da70f8fd Simplify the implementation of configmix.load() and .safe_load():
Franz Glasner <fzglas.hg@dom66.de>
parents: 217
diff changeset
62 ex = Configuration()
22
6a91db2c2469 A convenience function to load and merge a list of configuration files with different styles
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 13
diff changeset
63 else:
220
2034da70f8fd Simplify the implementation of configmix.load() and .safe_load():
Franz Glasner <fzglas.hg@dom66.de>
parents: 217
diff changeset
64 ex = merge(None, Configuration(defaults))
2034da70f8fd Simplify the implementation of configmix.load() and .safe_load():
Franz Glasner <fzglas.hg@dom66.de>
parents: 217
diff changeset
65 for f in files:
217
b869e792310e FIX: Extra merged and unsafe merges in configmix.safe_load
Franz Glasner <fzglas.hg@dom66.de>
parents: 216
diff changeset
66 ex = merge(_load_cfg_from_file(f), ex)
b869e792310e FIX: Extra merged and unsafe merges in configmix.safe_load
Franz Glasner <fzglas.hg@dom66.de>
parents: 216
diff changeset
67 return Configuration(ex)
22
6a91db2c2469 A convenience function to load and merge a list of configuration files with different styles
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 13
diff changeset
68
6a91db2c2469 A convenience function to load and merge a list of configuration files with different styles
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 13
diff changeset
69
172
8138d56d7cd3 ".load" and ".safe_load" get a keyword parameter "defaults" that allows the provision of a configuration dictionary with default settings
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 171
diff changeset
70 def safe_load(*files, **kwargs):
112
c50ad93eb5dc Implemented a "safe_load()" to load with safe merging
Franz Glasner <hg@dom66.de>
parents: 111
diff changeset
71 """Analogous to :func:`load` but do merging with :func:`safe_merge`
c50ad93eb5dc Implemented a "safe_load()" to load with safe merging
Franz Glasner <hg@dom66.de>
parents: 111
diff changeset
72 instead of :func:`merge`
c50ad93eb5dc Implemented a "safe_load()" to load with safe merging
Franz Glasner <hg@dom66.de>
parents: 111
diff changeset
73
c50ad93eb5dc Implemented a "safe_load()" to load with safe merging
Franz Glasner <hg@dom66.de>
parents: 111
diff changeset
74 """
172
8138d56d7cd3 ".load" and ".safe_load" get a keyword parameter "defaults" that allows the provision of a configuration dictionary with default settings
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 171
diff changeset
75 defaults = kwargs.get("defaults")
217
b869e792310e FIX: Extra merged and unsafe merges in configmix.safe_load
Franz Glasner <fzglas.hg@dom66.de>
parents: 216
diff changeset
76 if defaults is None:
220
2034da70f8fd Simplify the implementation of configmix.load() and .safe_load():
Franz Glasner <fzglas.hg@dom66.de>
parents: 217
diff changeset
77 ex = Configuration()
112
c50ad93eb5dc Implemented a "safe_load()" to load with safe merging
Franz Glasner <hg@dom66.de>
parents: 111
diff changeset
78 else:
220
2034da70f8fd Simplify the implementation of configmix.load() and .safe_load():
Franz Glasner <fzglas.hg@dom66.de>
parents: 217
diff changeset
79 ex = safe_merge(None, Configuration(defaults))
2034da70f8fd Simplify the implementation of configmix.load() and .safe_load():
Franz Glasner <fzglas.hg@dom66.de>
parents: 217
diff changeset
80 for f in files:
217
b869e792310e FIX: Extra merged and unsafe merges in configmix.safe_load
Franz Glasner <fzglas.hg@dom66.de>
parents: 216
diff changeset
81 ex = safe_merge(_load_cfg_from_file(f), ex)
b869e792310e FIX: Extra merged and unsafe merges in configmix.safe_load
Franz Glasner <fzglas.hg@dom66.de>
parents: 216
diff changeset
82 return Configuration(ex)
112
c50ad93eb5dc Implemented a "safe_load()" to load with safe merging
Franz Glasner <hg@dom66.de>
parents: 111
diff changeset
83
c50ad93eb5dc Implemented a "safe_load()" to load with safe merging
Franz Glasner <hg@dom66.de>
parents: 111
diff changeset
84
138
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
85 def _load_yaml(filename):
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
86 from . import yaml
166
b5ce9a8461bf Use the filesystem encoding explicitely where appropriate.
Franz Glasner <fzglas.hg@dom66.de>
parents: 165
diff changeset
87 with open(u2fs(filename), "rb") as yf:
138
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
88 return yaml.safe_load(yf)
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
89
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
90
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
91 def _load_json(filename):
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
92 from . import json
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
93 return json.load(filename)
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
94
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
95
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
96 def _load_py(filename):
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
97 from . import py
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
98 return py.load(filename)
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
99
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
100
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
101 def _load_ini(filename):
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
102 from . import ini
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
103 return ini.load(filename)
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
104
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
105
195
28e6c1413947 Added support for TOML style configuration files
Franz Glasner <fzglas.hg@dom66.de>
parents: 191
diff changeset
106 def _load_toml(filename):
28e6c1413947 Added support for TOML style configuration files
Franz Glasner <fzglas.hg@dom66.de>
parents: 191
diff changeset
107 from . import toml
28e6c1413947 Added support for TOML style configuration files
Franz Glasner <fzglas.hg@dom66.de>
parents: 191
diff changeset
108 return toml.load(filename)
28e6c1413947 Added support for TOML style configuration files
Franz Glasner <fzglas.hg@dom66.de>
parents: 191
diff changeset
109
28e6c1413947 Added support for TOML style configuration files
Franz Glasner <fzglas.hg@dom66.de>
parents: 191
diff changeset
110
180
e87fa5bd68e7 Implemented "try_determine_filemode()" to determine a file-mode from an Emacs-compatible declaration
Franz Glasner <fzglas.hg@dom66.de>
parents: 179
diff changeset
111 EMACS_MODELINE = re.compile(r"-\*-(.*?)-\*-")
e87fa5bd68e7 Implemented "try_determine_filemode()" to determine a file-mode from an Emacs-compatible declaration
Franz Glasner <fzglas.hg@dom66.de>
parents: 179
diff changeset
112 EMACS_MODE = re.compile(r"(?:\A\s*|;\s*)mode[:=]\s*([-_.a-zA-Z0-9]+)")
e87fa5bd68e7 Implemented "try_determine_filemode()" to determine a file-mode from an Emacs-compatible declaration
Franz Glasner <fzglas.hg@dom66.de>
parents: 179
diff changeset
113
e87fa5bd68e7 Implemented "try_determine_filemode()" to determine a file-mode from an Emacs-compatible declaration
Franz Glasner <fzglas.hg@dom66.de>
parents: 179
diff changeset
114
e87fa5bd68e7 Implemented "try_determine_filemode()" to determine a file-mode from an Emacs-compatible declaration
Franz Glasner <fzglas.hg@dom66.de>
parents: 179
diff changeset
115 def try_determine_filemode(filename):
e87fa5bd68e7 Implemented "try_determine_filemode()" to determine a file-mode from an Emacs-compatible declaration
Franz Glasner <fzglas.hg@dom66.de>
parents: 179
diff changeset
116 """Try to determine an explicitely given filemode from an Emacs-compatible
e87fa5bd68e7 Implemented "try_determine_filemode()" to determine a file-mode from an Emacs-compatible declaration
Franz Glasner <fzglas.hg@dom66.de>
parents: 179
diff changeset
117 mode declaration (e.g. ``mode=python``).
e87fa5bd68e7 Implemented "try_determine_filemode()" to determine a file-mode from an Emacs-compatible declaration
Franz Glasner <fzglas.hg@dom66.de>
parents: 179
diff changeset
118
e87fa5bd68e7 Implemented "try_determine_filemode()" to determine a file-mode from an Emacs-compatible declaration
Franz Glasner <fzglas.hg@dom66.de>
parents: 179
diff changeset
119 :param str filename:
e87fa5bd68e7 Implemented "try_determine_filemode()" to determine a file-mode from an Emacs-compatible declaration
Franz Glasner <fzglas.hg@dom66.de>
parents: 179
diff changeset
120 :return: the found mode string or `None`
e87fa5bd68e7 Implemented "try_determine_filemode()" to determine a file-mode from an Emacs-compatible declaration
Franz Glasner <fzglas.hg@dom66.de>
parents: 179
diff changeset
121 :rtype: str or None
e87fa5bd68e7 Implemented "try_determine_filemode()" to determine a file-mode from an Emacs-compatible declaration
Franz Glasner <fzglas.hg@dom66.de>
parents: 179
diff changeset
122
e87fa5bd68e7 Implemented "try_determine_filemode()" to determine a file-mode from an Emacs-compatible declaration
Franz Glasner <fzglas.hg@dom66.de>
parents: 179
diff changeset
123 Only the first two lines are searched for.
e87fa5bd68e7 Implemented "try_determine_filemode()" to determine a file-mode from an Emacs-compatible declaration
Franz Glasner <fzglas.hg@dom66.de>
parents: 179
diff changeset
124
206
5064e3a2e54a Doc: "configmix.try_determine_filemode()" got additional documentation
Franz Glasner <fzglas.hg@dom66.de>
parents: 197
diff changeset
125 Conveniently to be used in calls to :func:`~.set_assoc` to determine
5064e3a2e54a Doc: "configmix.try_determine_filemode()" got additional documentation
Franz Glasner <fzglas.hg@dom66.de>
parents: 197
diff changeset
126 the file-mode by content instead of filename extension.
5064e3a2e54a Doc: "configmix.try_determine_filemode()" got additional documentation
Franz Glasner <fzglas.hg@dom66.de>
parents: 197
diff changeset
127
180
e87fa5bd68e7 Implemented "try_determine_filemode()" to determine a file-mode from an Emacs-compatible declaration
Franz Glasner <fzglas.hg@dom66.de>
parents: 179
diff changeset
128 """
e87fa5bd68e7 Implemented "try_determine_filemode()" to determine a file-mode from an Emacs-compatible declaration
Franz Glasner <fzglas.hg@dom66.de>
parents: 179
diff changeset
129 with io.open(filename, encoding="ascii", errors="replace") as f:
e87fa5bd68e7 Implemented "try_determine_filemode()" to determine a file-mode from an Emacs-compatible declaration
Franz Glasner <fzglas.hg@dom66.de>
parents: 179
diff changeset
130 idx = 0
e87fa5bd68e7 Implemented "try_determine_filemode()" to determine a file-mode from an Emacs-compatible declaration
Franz Glasner <fzglas.hg@dom66.de>
parents: 179
diff changeset
131 for l in f:
e87fa5bd68e7 Implemented "try_determine_filemode()" to determine a file-mode from an Emacs-compatible declaration
Franz Glasner <fzglas.hg@dom66.de>
parents: 179
diff changeset
132 idx += 1
e87fa5bd68e7 Implemented "try_determine_filemode()" to determine a file-mode from an Emacs-compatible declaration
Franz Glasner <fzglas.hg@dom66.de>
parents: 179
diff changeset
133 mo = EMACS_MODELINE.search(l)
e87fa5bd68e7 Implemented "try_determine_filemode()" to determine a file-mode from an Emacs-compatible declaration
Franz Glasner <fzglas.hg@dom66.de>
parents: 179
diff changeset
134 if mo:
e87fa5bd68e7 Implemented "try_determine_filemode()" to determine a file-mode from an Emacs-compatible declaration
Franz Glasner <fzglas.hg@dom66.de>
parents: 179
diff changeset
135 mo = EMACS_MODE.search(mo.group(1))
e87fa5bd68e7 Implemented "try_determine_filemode()" to determine a file-mode from an Emacs-compatible declaration
Franz Glasner <fzglas.hg@dom66.de>
parents: 179
diff changeset
136 if mo:
e87fa5bd68e7 Implemented "try_determine_filemode()" to determine a file-mode from an Emacs-compatible declaration
Franz Glasner <fzglas.hg@dom66.de>
parents: 179
diff changeset
137 return mo.group(1)
e87fa5bd68e7 Implemented "try_determine_filemode()" to determine a file-mode from an Emacs-compatible declaration
Franz Glasner <fzglas.hg@dom66.de>
parents: 179
diff changeset
138 if idx >= 2:
e87fa5bd68e7 Implemented "try_determine_filemode()" to determine a file-mode from an Emacs-compatible declaration
Franz Glasner <fzglas.hg@dom66.de>
parents: 179
diff changeset
139 break
e87fa5bd68e7 Implemented "try_determine_filemode()" to determine a file-mode from an Emacs-compatible declaration
Franz Glasner <fzglas.hg@dom66.de>
parents: 179
diff changeset
140 return None
e87fa5bd68e7 Implemented "try_determine_filemode()" to determine a file-mode from an Emacs-compatible declaration
Franz Glasner <fzglas.hg@dom66.de>
parents: 179
diff changeset
141
e87fa5bd68e7 Implemented "try_determine_filemode()" to determine a file-mode from an Emacs-compatible declaration
Franz Glasner <fzglas.hg@dom66.de>
parents: 179
diff changeset
142
178
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
143 DEFAULT_MODE_LOADERS = {
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
144 "python": _load_py,
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
145 "yaml": _load_yaml,
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
146 "conf": _load_ini,
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
147 "conf-windows": _load_ini,
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
148 "ini": _load_ini,
195
28e6c1413947 Added support for TOML style configuration files
Franz Glasner <fzglas.hg@dom66.de>
parents: 191
diff changeset
149 "toml": _load_toml,
197
7865f28038a4 Add the "conf-toml" mode mapping to the TOML loader
Franz Glasner <fzglas.hg@dom66.de>
parents: 195
diff changeset
150 "conf-toml": _load_toml,
178
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
151 "javascript": _load_json,
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
152 "json": _load_json,
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
153 }
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
154 """Default associations between file modes and loader functions"""
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
155
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
156
181
7cfdc972af42 Refactor: Renamed public functions to be conform with the new loader search
Franz Glasner <fzglas.hg@dom66.de>
parents: 180
diff changeset
157 DEFAULT_ASSOC = [
178
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
158 ("*.yml", "yaml"),
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
159 ("*.yaml", "yaml"),
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
160 ("*.json", "json"),
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
161 ("*.py", "python"),
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
162 ("*.ini", "conf"),
195
28e6c1413947 Added support for TOML style configuration files
Franz Glasner <fzglas.hg@dom66.de>
parents: 191
diff changeset
163 ("*.toml", "toml"),
171
1ff11462a5c1 The associations from filename extensions to parsers are "fnmatch" style patterns now.
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 170
diff changeset
164 ]
178
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
165 """The builtin default associations of filename extensions with
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
166 file modes -- in that order.
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
167
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
168 The "mode" part may be a string or a callable with a filename
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
169 parameter that returns the mode string for the file or `None` if it
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
170 can not determined.
171
1ff11462a5c1 The associations from filename extensions to parsers are "fnmatch" style patterns now.
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 170
diff changeset
171
1ff11462a5c1 The associations from filename extensions to parsers are "fnmatch" style patterns now.
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 170
diff changeset
172 """
139
c87b0dc54e1d Allow custom configuration filename extensions and custom loaders that can handle custom configuration file syntax styles
Franz Glasner <hg@dom66.de>
parents: 138
diff changeset
173
c87b0dc54e1d Allow custom configuration filename extensions and custom loaders that can handle custom configuration file syntax styles
Franz Glasner <hg@dom66.de>
parents: 138
diff changeset
174
188
17b938ccecb8 Rename the DEFAULT_LOADER marker to USE_DEFAULT_ASSOC
Franz Glasner <fzglas.hg@dom66.de>
parents: 187
diff changeset
175 USE_DEFAULT_ASSOC = object()
181
7cfdc972af42 Refactor: Renamed public functions to be conform with the new loader search
Franz Glasner <fzglas.hg@dom66.de>
parents: 180
diff changeset
176 """Marker for the default association for an extension.
139
c87b0dc54e1d Allow custom configuration filename extensions and custom loaders that can handle custom configuration file syntax styles
Franz Glasner <hg@dom66.de>
parents: 138
diff changeset
177
181
7cfdc972af42 Refactor: Renamed public functions to be conform with the new loader search
Franz Glasner <fzglas.hg@dom66.de>
parents: 180
diff changeset
178 To be used in :func:`set_assoc`.
139
c87b0dc54e1d Allow custom configuration filename extensions and custom loaders that can handle custom configuration file syntax styles
Franz Glasner <hg@dom66.de>
parents: 138
diff changeset
179 """
c87b0dc54e1d Allow custom configuration filename extensions and custom loaders that can handle custom configuration file syntax styles
Franz Glasner <hg@dom66.de>
parents: 138
diff changeset
180
181
7cfdc972af42 Refactor: Renamed public functions to be conform with the new loader search
Franz Glasner <fzglas.hg@dom66.de>
parents: 180
diff changeset
181
7cfdc972af42 Refactor: Renamed public functions to be conform with the new loader search
Franz Glasner <fzglas.hg@dom66.de>
parents: 180
diff changeset
182 def get_default_assoc(pattern):
7cfdc972af42 Refactor: Renamed public functions to be conform with the new loader search
Franz Glasner <fzglas.hg@dom66.de>
parents: 180
diff changeset
183 """Return the default file-mode association for the :mod:`fnmatch`
7cfdc972af42 Refactor: Renamed public functions to be conform with the new loader search
Franz Glasner <fzglas.hg@dom66.de>
parents: 180
diff changeset
184 pattern `pattern`.
171
1ff11462a5c1 The associations from filename extensions to parsers are "fnmatch" style patterns now.
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 170
diff changeset
185
1ff11462a5c1 The associations from filename extensions to parsers are "fnmatch" style patterns now.
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 170
diff changeset
186 :raises: :class:`KeyError` if the `pattern` is not found.
1ff11462a5c1 The associations from filename extensions to parsers are "fnmatch" style patterns now.
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 170
diff changeset
187
1ff11462a5c1 The associations from filename extensions to parsers are "fnmatch" style patterns now.
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 170
diff changeset
188 """
181
7cfdc972af42 Refactor: Renamed public functions to be conform with the new loader search
Franz Glasner <fzglas.hg@dom66.de>
parents: 180
diff changeset
189 for pat, fmode in DEFAULT_ASSOC:
171
1ff11462a5c1 The associations from filename extensions to parsers are "fnmatch" style patterns now.
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 170
diff changeset
190 if pattern == pat:
181
7cfdc972af42 Refactor: Renamed public functions to be conform with the new loader search
Franz Glasner <fzglas.hg@dom66.de>
parents: 180
diff changeset
191 return fmode
171
1ff11462a5c1 The associations from filename extensions to parsers are "fnmatch" style patterns now.
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 170
diff changeset
192 else:
1ff11462a5c1 The associations from filename extensions to parsers are "fnmatch" style patterns now.
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 170
diff changeset
193 raise KeyError("No loader for pattern %r" % pattern)
1ff11462a5c1 The associations from filename extensions to parsers are "fnmatch" style patterns now.
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 170
diff changeset
194
1ff11462a5c1 The associations from filename extensions to parsers are "fnmatch" style patterns now.
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 170
diff changeset
195
189
0d0980ed74cc Rename the "_mode_loaders" variable to "mode_loaders" and make is therefore a "public" item
Franz Glasner <fzglas.hg@dom66.de>
parents: 188
diff changeset
196 mode_loaders = {}
178
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
197 """All configured associations between file modes and loader functions.
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
198
191
8af600d0e5c0 FIX: Docu: added missing backtick
Franz Glasner <fzglas.hg@dom66.de>
parents: 189
diff changeset
199 See :data:`DEFAULT_MODE_LOADERS`.
178
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
200
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
201 """
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
202
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
203 _extensions = []
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
204 """All configured assiciations of filename extensions with file modes.
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
205
181
7cfdc972af42 Refactor: Renamed public functions to be conform with the new loader search
Franz Glasner <fzglas.hg@dom66.de>
parents: 180
diff changeset
206 See :data:`DEFAULT_ASSOC`
178
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
207
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
208 """
139
c87b0dc54e1d Allow custom configuration filename extensions and custom loaders that can handle custom configuration file syntax styles
Franz Glasner <hg@dom66.de>
parents: 138
diff changeset
209
c87b0dc54e1d Allow custom configuration filename extensions and custom loaders that can handle custom configuration file syntax styles
Franz Glasner <hg@dom66.de>
parents: 138
diff changeset
210
181
7cfdc972af42 Refactor: Renamed public functions to be conform with the new loader search
Franz Glasner <fzglas.hg@dom66.de>
parents: 180
diff changeset
211 def clear_assoc():
139
c87b0dc54e1d Allow custom configuration filename extensions and custom loaders that can handle custom configuration file syntax styles
Franz Glasner <hg@dom66.de>
parents: 138
diff changeset
212 """Remove all configured loader associations.
c87b0dc54e1d Allow custom configuration filename extensions and custom loaders that can handle custom configuration file syntax styles
Franz Glasner <hg@dom66.de>
parents: 138
diff changeset
213
187
d2eb83720ad8 FIX: Docu: names of predefined constants
Franz Glasner <fzglas.hg@dom66.de>
parents: 186
diff changeset
214 The :data:`.DEFAULT_ASSOC` are **not** changed.
139
c87b0dc54e1d Allow custom configuration filename extensions and custom loaders that can handle custom configuration file syntax styles
Franz Glasner <hg@dom66.de>
parents: 138
diff changeset
215
c87b0dc54e1d Allow custom configuration filename extensions and custom loaders that can handle custom configuration file syntax styles
Franz Glasner <hg@dom66.de>
parents: 138
diff changeset
216 """
181
7cfdc972af42 Refactor: Renamed public functions to be conform with the new loader search
Franz Glasner <fzglas.hg@dom66.de>
parents: 180
diff changeset
217 del _extensions[:]
139
c87b0dc54e1d Allow custom configuration filename extensions and custom loaders that can handle custom configuration file syntax styles
Franz Glasner <hg@dom66.de>
parents: 138
diff changeset
218
c87b0dc54e1d Allow custom configuration filename extensions and custom loaders that can handle custom configuration file syntax styles
Franz Glasner <hg@dom66.de>
parents: 138
diff changeset
219
181
7cfdc972af42 Refactor: Renamed public functions to be conform with the new loader search
Franz Glasner <fzglas.hg@dom66.de>
parents: 180
diff changeset
220 def get_assoc(pattern):
171
1ff11462a5c1 The associations from filename extensions to parsers are "fnmatch" style patterns now.
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 170
diff changeset
221 """Return the default loader for the :mod:`fnmatch` pattern `pattern`.
1ff11462a5c1 The associations from filename extensions to parsers are "fnmatch" style patterns now.
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 170
diff changeset
222
1ff11462a5c1 The associations from filename extensions to parsers are "fnmatch" style patterns now.
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 170
diff changeset
223 :raises: :class:`KeyError` if the `pattern` is not found.
139
c87b0dc54e1d Allow custom configuration filename extensions and custom loaders that can handle custom configuration file syntax styles
Franz Glasner <hg@dom66.de>
parents: 138
diff changeset
224
171
1ff11462a5c1 The associations from filename extensions to parsers are "fnmatch" style patterns now.
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 170
diff changeset
225 """
181
7cfdc972af42 Refactor: Renamed public functions to be conform with the new loader search
Franz Glasner <fzglas.hg@dom66.de>
parents: 180
diff changeset
226 for pat, fmode in _extensions:
171
1ff11462a5c1 The associations from filename extensions to parsers are "fnmatch" style patterns now.
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 170
diff changeset
227 if pattern == pat:
181
7cfdc972af42 Refactor: Renamed public functions to be conform with the new loader search
Franz Glasner <fzglas.hg@dom66.de>
parents: 180
diff changeset
228 return fmode
171
1ff11462a5c1 The associations from filename extensions to parsers are "fnmatch" style patterns now.
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 170
diff changeset
229 else:
181
7cfdc972af42 Refactor: Renamed public functions to be conform with the new loader search
Franz Glasner <fzglas.hg@dom66.de>
parents: 180
diff changeset
230 raise KeyError("No associated file-mode for pattern %r" % pattern)
171
1ff11462a5c1 The associations from filename extensions to parsers are "fnmatch" style patterns now.
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 170
diff changeset
231
1ff11462a5c1 The associations from filename extensions to parsers are "fnmatch" style patterns now.
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 170
diff changeset
232
186
fa101fb0cd7a Implement an "append" keyword to "configmix.set_assoc()"
Franz Glasner <fzglas.hg@dom66.de>
parents: 181
diff changeset
233 def set_assoc(fnpattern, mode, append=False):
179
62db35db8939 Docu: formatting
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 178
diff changeset
234 """Associate a :mod:`fnmatch` style pattern `fnpattern` with a
62db35db8939 Docu: formatting
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 178
diff changeset
235 file-mode `mode` that determines what will be called when
62db35db8939 Docu: formatting
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 178
diff changeset
236 :func:`load` encounters a file argument that matches `fnpattern`.
171
1ff11462a5c1 The associations from filename extensions to parsers are "fnmatch" style patterns now.
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 170
diff changeset
237
179
62db35db8939 Docu: formatting
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 178
diff changeset
238 :param str fnpattern: the :mod:`fnmatch` pattern to associate a loader
62db35db8939 Docu: formatting
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 178
diff changeset
239 with
186
fa101fb0cd7a Implement an "append" keyword to "configmix.set_assoc()"
Franz Glasner <fzglas.hg@dom66.de>
parents: 181
diff changeset
240 :param mode: a mode string or a callable that accepts a `filename`
fa101fb0cd7a Implement an "append" keyword to "configmix.set_assoc()"
Franz Glasner <fzglas.hg@dom66.de>
parents: 181
diff changeset
241 argument and returns a file-mode for the given file
fa101fb0cd7a Implement an "append" keyword to "configmix.set_assoc()"
Franz Glasner <fzglas.hg@dom66.de>
parents: 181
diff changeset
242 (or `None`)
fa101fb0cd7a Implement an "append" keyword to "configmix.set_assoc()"
Franz Glasner <fzglas.hg@dom66.de>
parents: 181
diff changeset
243 :type mode: str or callable
139
c87b0dc54e1d Allow custom configuration filename extensions and custom loaders that can handle custom configuration file syntax styles
Franz Glasner <hg@dom66.de>
parents: 138
diff changeset
244
186
fa101fb0cd7a Implement an "append" keyword to "configmix.set_assoc()"
Franz Glasner <fzglas.hg@dom66.de>
parents: 181
diff changeset
245 :keyword bool append: If `False` (which is the default) then this
fa101fb0cd7a Implement an "append" keyword to "configmix.set_assoc()"
Franz Glasner <fzglas.hg@dom66.de>
parents: 181
diff changeset
246 function inserts the given pattern at the head position of the
fa101fb0cd7a Implement an "append" keyword to "configmix.set_assoc()"
Franz Glasner <fzglas.hg@dom66.de>
parents: 181
diff changeset
247 currently defined associations, if `True` the pattern will be appended
171
1ff11462a5c1 The associations from filename extensions to parsers are "fnmatch" style patterns now.
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 170
diff changeset
248
1ff11462a5c1 The associations from filename extensions to parsers are "fnmatch" style patterns now.
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 170
diff changeset
249 The OS specific case-sensitivity behaviour of
175
327032bb0f6b Docu: wording
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 174
diff changeset
250 :func:`fnmatch.fnmatch` applies (i.e. :func:`os.path.normpath`
327032bb0f6b Docu: wording
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 174
diff changeset
251 will be called for both arguments).
141
647782859ae1 An extra hint that filename extension comparisons for loader lookup are case-insensitive
Franz Glasner <hg@dom66.de>
parents: 139
diff changeset
252
188
17b938ccecb8 Rename the DEFAULT_LOADER marker to USE_DEFAULT_ASSOC
Franz Glasner <fzglas.hg@dom66.de>
parents: 187
diff changeset
253 If `loader` is :data:`.USE_DEFAULT_ASSOC` then the default association
187
d2eb83720ad8 FIX: Docu: names of predefined constants
Franz Glasner <fzglas.hg@dom66.de>
parents: 186
diff changeset
254 from :data:`.DEFAULT_ASSOC` will be used -- if any.
139
c87b0dc54e1d Allow custom configuration filename extensions and custom loaders that can handle custom configuration file syntax styles
Franz Glasner <hg@dom66.de>
parents: 138
diff changeset
255
c87b0dc54e1d Allow custom configuration filename extensions and custom loaders that can handle custom configuration file syntax styles
Franz Glasner <hg@dom66.de>
parents: 138
diff changeset
256 """
188
17b938ccecb8 Rename the DEFAULT_LOADER marker to USE_DEFAULT_ASSOC
Franz Glasner <fzglas.hg@dom66.de>
parents: 187
diff changeset
257 if mode is USE_DEFAULT_ASSOC:
181
7cfdc972af42 Refactor: Renamed public functions to be conform with the new loader search
Franz Glasner <fzglas.hg@dom66.de>
parents: 180
diff changeset
258 for p, m in DEFAULT_ASSOC:
178
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
259 if p == fnpattern:
186
fa101fb0cd7a Implement an "append" keyword to "configmix.set_assoc()"
Franz Glasner <fzglas.hg@dom66.de>
parents: 181
diff changeset
260 if append:
fa101fb0cd7a Implement an "append" keyword to "configmix.set_assoc()"
Franz Glasner <fzglas.hg@dom66.de>
parents: 181
diff changeset
261 _extensions.append((fnpattern, m))
fa101fb0cd7a Implement an "append" keyword to "configmix.set_assoc()"
Franz Glasner <fzglas.hg@dom66.de>
parents: 181
diff changeset
262 else:
fa101fb0cd7a Implement an "append" keyword to "configmix.set_assoc()"
Franz Glasner <fzglas.hg@dom66.de>
parents: 181
diff changeset
263 _extensions.insert(0, (fnpattern, m))
171
1ff11462a5c1 The associations from filename extensions to parsers are "fnmatch" style patterns now.
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 170
diff changeset
264 break
1ff11462a5c1 The associations from filename extensions to parsers are "fnmatch" style patterns now.
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 170
diff changeset
265 else:
178
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
266 raise ValueError("no DEFAULT mode for pattern: %r" % fnpattern)
139
c87b0dc54e1d Allow custom configuration filename extensions and custom loaders that can handle custom configuration file syntax styles
Franz Glasner <hg@dom66.de>
parents: 138
diff changeset
267 else:
186
fa101fb0cd7a Implement an "append" keyword to "configmix.set_assoc()"
Franz Glasner <fzglas.hg@dom66.de>
parents: 181
diff changeset
268 if append:
fa101fb0cd7a Implement an "append" keyword to "configmix.set_assoc()"
Franz Glasner <fzglas.hg@dom66.de>
parents: 181
diff changeset
269 _extensions.append((fnpattern, mode))
fa101fb0cd7a Implement an "append" keyword to "configmix.set_assoc()"
Franz Glasner <fzglas.hg@dom66.de>
parents: 181
diff changeset
270 else:
fa101fb0cd7a Implement an "append" keyword to "configmix.set_assoc()"
Franz Glasner <fzglas.hg@dom66.de>
parents: 181
diff changeset
271 _extensions.insert(0, (fnpattern, mode))
138
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
272
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
273
22
6a91db2c2469 A convenience function to load and merge a list of configuration files with different styles
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 13
diff changeset
274 def _load_cfg_from_file(filename):
178
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
275 for p, m in _extensions:
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
276 if fnmatch.fnmatch(filename, p):
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
277 if callable(m):
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
278 m = m(filename)
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
279 if m is None:
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
280 continue
189
0d0980ed74cc Rename the "_mode_loaders" variable to "mode_loaders" and make is therefore a "public" item
Franz Glasner <fzglas.hg@dom66.de>
parents: 188
diff changeset
281 return mode_loaders[m](filename)
22
6a91db2c2469 A convenience function to load and merge a list of configuration files with different styles
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 13
diff changeset
282 else:
6a91db2c2469 A convenience function to load and merge a list of configuration files with different styles
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 13
diff changeset
283 raise ValueError("Unknown configuration file type for filename "
6a91db2c2469 A convenience function to load and merge a list of configuration files with different styles
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 13
diff changeset
284 "%r" % filename)
8
7090c295c940 Two differend tree merge function implementations: not yet finished
Franz Glasner <hg@dom66.de>
parents: 5
diff changeset
285
7090c295c940 Two differend tree merge function implementations: not yet finished
Franz Glasner <hg@dom66.de>
parents: 5
diff changeset
286
11
aecb36d4025f Deactivate the "dict_merge()" function from yconfig
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 10
diff changeset
287 if 0:
aecb36d4025f Deactivate the "dict_merge()" function from yconfig
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 10
diff changeset
288 #
aecb36d4025f Deactivate the "dict_merge()" function from yconfig
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 10
diff changeset
289 # From: https://github.com/jet9/python-yconfig/blob/master/yconfig.py
aecb36d4025f Deactivate the "dict_merge()" function from yconfig
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 10
diff changeset
290 # License: BSD License
aecb36d4025f Deactivate the "dict_merge()" function from yconfig
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 10
diff changeset
291 #
aecb36d4025f Deactivate the "dict_merge()" function from yconfig
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 10
diff changeset
292 def dict_merge(a, b):
aecb36d4025f Deactivate the "dict_merge()" function from yconfig
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 10
diff changeset
293 """Recursively merges dict's. not just simple a['key'] = b['key'], if
aecb36d4025f Deactivate the "dict_merge()" function from yconfig
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 10
diff changeset
294 both a and bhave a key who's value is a dict then dict_merge is called
aecb36d4025f Deactivate the "dict_merge()" function from yconfig
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 10
diff changeset
295 on both values and the result stored in the returned dictionary."""
8
7090c295c940 Two differend tree merge function implementations: not yet finished
Franz Glasner <hg@dom66.de>
parents: 5
diff changeset
296
11
aecb36d4025f Deactivate the "dict_merge()" function from yconfig
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 10
diff changeset
297 if not isinstance(b, dict):
aecb36d4025f Deactivate the "dict_merge()" function from yconfig
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 10
diff changeset
298 return b
207
b3b5ed34d180 Handle most flake8 errors and warnings.
Franz Glasner <fzglas.hg@dom66.de>
parents: 206
diff changeset
299 result = deepcopy(a) # noqa
11
aecb36d4025f Deactivate the "dict_merge()" function from yconfig
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 10
diff changeset
300 for k, v in b.iteritems():
aecb36d4025f Deactivate the "dict_merge()" function from yconfig
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 10
diff changeset
301 if k in result and isinstance(result[k], dict):
aecb36d4025f Deactivate the "dict_merge()" function from yconfig
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 10
diff changeset
302 result[k] = dict_merge(result[k], v)
aecb36d4025f Deactivate the "dict_merge()" function from yconfig
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 10
diff changeset
303 else:
207
b3b5ed34d180 Handle most flake8 errors and warnings.
Franz Glasner <fzglas.hg@dom66.de>
parents: 206
diff changeset
304 result[k] = deepcopy(v) # noqa
11
aecb36d4025f Deactivate the "dict_merge()" function from yconfig
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 10
diff changeset
305 return result
8
7090c295c940 Two differend tree merge function implementations: not yet finished
Franz Glasner <hg@dom66.de>
parents: 5
diff changeset
306
7090c295c940 Two differend tree merge function implementations: not yet finished
Franz Glasner <hg@dom66.de>
parents: 5
diff changeset
307
144
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
308 def merge(user, default, filter_comments=True):
110
29cf359ddf4d Remove the "_first" parameter from "merge" and "safe_merge" by splitting into two functions
Franz Glasner <hg@dom66.de>
parents: 108
diff changeset
309 """Logically merge the configuration in `user` into `default`.
98
d6ba53ce2091 Better documentation of the core function in "configmix"
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 96
diff changeset
310
d6ba53ce2091 Better documentation of the core function in "configmix"
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 96
diff changeset
311 :param ~configmix.config.Configuration user:
110
29cf359ddf4d Remove the "_first" parameter from "merge" and "safe_merge" by splitting into two functions
Franz Glasner <hg@dom66.de>
parents: 108
diff changeset
312 the new configuration that will be logically merged
29cf359ddf4d Remove the "_first" parameter from "merge" and "safe_merge" by splitting into two functions
Franz Glasner <hg@dom66.de>
parents: 108
diff changeset
313 into `default`
98
d6ba53ce2091 Better documentation of the core function in "configmix"
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 96
diff changeset
314 :param ~configmix.config.Configuration default:
110
29cf359ddf4d Remove the "_first" parameter from "merge" and "safe_merge" by splitting into two functions
Franz Glasner <hg@dom66.de>
parents: 108
diff changeset
315 the base configuration where `user` is logically merged into
144
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
316 :param bool filter_comments: flag whether to filter comment keys that
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
317 start with any of the items in :data:`COMMENTS`
110
29cf359ddf4d Remove the "_first" parameter from "merge" and "safe_merge" by splitting into two functions
Franz Glasner <hg@dom66.de>
parents: 108
diff changeset
318 :returns: `user` with the necessary amendments from `default`.
29cf359ddf4d Remove the "_first" parameter from "merge" and "safe_merge" by splitting into two functions
Franz Glasner <hg@dom66.de>
parents: 108
diff changeset
319 If `user` is ``None`` then `default` is returned.
29cf359ddf4d Remove the "_first" parameter from "merge" and "safe_merge" by splitting into two functions
Franz Glasner <hg@dom66.de>
parents: 108
diff changeset
320
144
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
321 .. note:: The configuration in `user` is augmented/changed
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
322 **inplace**.
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
323
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
324 The configuration in `default` will be changed **inplace**
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
325 when filtering out comments (which is the default).
8
7090c295c940 Two differend tree merge function implementations: not yet finished
Franz Glasner <hg@dom66.de>
parents: 5
diff changeset
326
7090c295c940 Two differend tree merge function implementations: not yet finished
Franz Glasner <hg@dom66.de>
parents: 5
diff changeset
327 From http://stackoverflow.com/questions/823196/yaml-merge-in-python
7090c295c940 Two differend tree merge function implementations: not yet finished
Franz Glasner <hg@dom66.de>
parents: 5
diff changeset
328
7090c295c940 Two differend tree merge function implementations: not yet finished
Franz Glasner <hg@dom66.de>
parents: 5
diff changeset
329 """
110
29cf359ddf4d Remove the "_first" parameter from "merge" and "safe_merge" by splitting into two functions
Franz Glasner <hg@dom66.de>
parents: 108
diff changeset
330 if user is None:
144
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
331 if filter_comments:
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
332 _filter_comments(default)
13
24ba462b9b4b Return the `default' argument when the given `user' argument is `None' and when it is the first call on merge
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 11
diff changeset
333 return default
144
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
334 if filter_comments:
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
335 _filter_comments(user)
8
7090c295c940 Two differend tree merge function implementations: not yet finished
Franz Glasner <hg@dom66.de>
parents: 5
diff changeset
336 if isinstance(user, dict) and isinstance(default, dict):
9
6835a5663008 FIX: Style
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 8
diff changeset
337 for k, v in default.items():
144
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
338 if filter_comments and _is_comment(k):
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
339 continue
8
7090c295c940 Two differend tree merge function implementations: not yet finished
Franz Glasner <hg@dom66.de>
parents: 5
diff changeset
340 if k not in user:
7090c295c940 Two differend tree merge function implementations: not yet finished
Franz Glasner <hg@dom66.de>
parents: 5
diff changeset
341 user[k] = v
7090c295c940 Two differend tree merge function implementations: not yet finished
Franz Glasner <hg@dom66.de>
parents: 5
diff changeset
342 else:
144
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
343 user[k] = _merge(user[k], v, filter_comments)
8
7090c295c940 Two differend tree merge function implementations: not yet finished
Franz Glasner <hg@dom66.de>
parents: 5
diff changeset
344 return user
10
58af59d5af40 A "safe_merge" that makes (shallow) copies instead of directly manipulating given containers
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 9
diff changeset
345
58af59d5af40 A "safe_merge" that makes (shallow) copies instead of directly manipulating given containers
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 9
diff changeset
346
144
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
347 def _merge(user, default, filter_comments):
110
29cf359ddf4d Remove the "_first" parameter from "merge" and "safe_merge" by splitting into two functions
Franz Glasner <hg@dom66.de>
parents: 108
diff changeset
348 """Recursion helper for :meth:`merge`
29cf359ddf4d Remove the "_first" parameter from "merge" and "safe_merge" by splitting into two functions
Franz Glasner <hg@dom66.de>
parents: 108
diff changeset
349
29cf359ddf4d Remove the "_first" parameter from "merge" and "safe_merge" by splitting into two functions
Franz Glasner <hg@dom66.de>
parents: 108
diff changeset
350 """
29cf359ddf4d Remove the "_first" parameter from "merge" and "safe_merge" by splitting into two functions
Franz Glasner <hg@dom66.de>
parents: 108
diff changeset
351 if isinstance(user, dict) and isinstance(default, dict):
29cf359ddf4d Remove the "_first" parameter from "merge" and "safe_merge" by splitting into two functions
Franz Glasner <hg@dom66.de>
parents: 108
diff changeset
352 for k, v in default.items():
144
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
353 if filter_comments and _is_comment(k):
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
354 continue
110
29cf359ddf4d Remove the "_first" parameter from "merge" and "safe_merge" by splitting into two functions
Franz Glasner <hg@dom66.de>
parents: 108
diff changeset
355 if k not in user:
29cf359ddf4d Remove the "_first" parameter from "merge" and "safe_merge" by splitting into two functions
Franz Glasner <hg@dom66.de>
parents: 108
diff changeset
356 user[k] = v
29cf359ddf4d Remove the "_first" parameter from "merge" and "safe_merge" by splitting into two functions
Franz Glasner <hg@dom66.de>
parents: 108
diff changeset
357 else:
144
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
358 user[k] = _merge(user[k], v, filter_comments)
110
29cf359ddf4d Remove the "_first" parameter from "merge" and "safe_merge" by splitting into two functions
Franz Glasner <hg@dom66.de>
parents: 108
diff changeset
359 return user
29cf359ddf4d Remove the "_first" parameter from "merge" and "safe_merge" by splitting into two functions
Franz Glasner <hg@dom66.de>
parents: 108
diff changeset
360
29cf359ddf4d Remove the "_first" parameter from "merge" and "safe_merge" by splitting into two functions
Franz Glasner <hg@dom66.de>
parents: 108
diff changeset
361
144
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
362 def safe_merge(user, default, filter_comments=True):
111
d51a18e5b0e3 Reimplement configmix.safe_merge() do to a deepcopy of all source configurations when merging.
Franz Glasner <hg@dom66.de>
parents: 110
diff changeset
363 """A more safe version of :func:`merge` that makes deep copies of
13
24ba462b9b4b Return the `default' argument when the given `user' argument is `None' and when it is the first call on merge
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 11
diff changeset
364 the returned container objects.
24ba462b9b4b Return the `default' argument when the given `user' argument is `None' and when it is the first call on merge
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 11
diff changeset
365
144
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
366 Contrary to :func:`merge` no given argument is ever changed
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
367 inplace. Every object from `default` is decoupled from the result
165
6ca90e80f4f4 FIX: Docu: wording
Franz Glasner <fzglas.hg@dom66.de>
parents: 163
diff changeset
368 -- so changing the `default` configuration later does not propagate
144
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
369 into a merged configuration later.
111
d51a18e5b0e3 Reimplement configmix.safe_merge() do to a deepcopy of all source configurations when merging.
Franz Glasner <hg@dom66.de>
parents: 110
diff changeset
370
10
58af59d5af40 A "safe_merge" that makes (shallow) copies instead of directly manipulating given containers
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 9
diff changeset
371 """
110
29cf359ddf4d Remove the "_first" parameter from "merge" and "safe_merge" by splitting into two functions
Franz Glasner <hg@dom66.de>
parents: 108
diff changeset
372 if user is None:
144
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
373 if filter_comments:
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
374 _filter_comments(default)
111
d51a18e5b0e3 Reimplement configmix.safe_merge() do to a deepcopy of all source configurations when merging.
Franz Glasner <hg@dom66.de>
parents: 110
diff changeset
375 return copy.deepcopy(default)
d51a18e5b0e3 Reimplement configmix.safe_merge() do to a deepcopy of all source configurations when merging.
Franz Glasner <hg@dom66.de>
parents: 110
diff changeset
376 user = copy.deepcopy(user)
144
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
377 if filter_comments:
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
378 _filter_comments(user)
10
58af59d5af40 A "safe_merge" that makes (shallow) copies instead of directly manipulating given containers
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 9
diff changeset
379 if isinstance(user, dict) and isinstance(default, dict):
58af59d5af40 A "safe_merge" that makes (shallow) copies instead of directly manipulating given containers
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 9
diff changeset
380 for k, v in default.items():
144
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
381 if filter_comments and _is_comment(k):
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
382 continue
10
58af59d5af40 A "safe_merge" that makes (shallow) copies instead of directly manipulating given containers
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 9
diff changeset
383 if k not in user:
111
d51a18e5b0e3 Reimplement configmix.safe_merge() do to a deepcopy of all source configurations when merging.
Franz Glasner <hg@dom66.de>
parents: 110
diff changeset
384 user[k] = copy.deepcopy(v)
10
58af59d5af40 A "safe_merge" that makes (shallow) copies instead of directly manipulating given containers
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 9
diff changeset
385 else:
144
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
386 user[k] = _safe_merge(user[k], v, filter_comments)
10
58af59d5af40 A "safe_merge" that makes (shallow) copies instead of directly manipulating given containers
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 9
diff changeset
387 return user
111
d51a18e5b0e3 Reimplement configmix.safe_merge() do to a deepcopy of all source configurations when merging.
Franz Glasner <hg@dom66.de>
parents: 110
diff changeset
388
d51a18e5b0e3 Reimplement configmix.safe_merge() do to a deepcopy of all source configurations when merging.
Franz Glasner <hg@dom66.de>
parents: 110
diff changeset
389
144
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
390 def _safe_merge(user, default, filter_comments):
111
d51a18e5b0e3 Reimplement configmix.safe_merge() do to a deepcopy of all source configurations when merging.
Franz Glasner <hg@dom66.de>
parents: 110
diff changeset
391 """Recursion helper for :meth:`safe_merge`
d51a18e5b0e3 Reimplement configmix.safe_merge() do to a deepcopy of all source configurations when merging.
Franz Glasner <hg@dom66.de>
parents: 110
diff changeset
392
d51a18e5b0e3 Reimplement configmix.safe_merge() do to a deepcopy of all source configurations when merging.
Franz Glasner <hg@dom66.de>
parents: 110
diff changeset
393 """
d51a18e5b0e3 Reimplement configmix.safe_merge() do to a deepcopy of all source configurations when merging.
Franz Glasner <hg@dom66.de>
parents: 110
diff changeset
394 if isinstance(user, dict) and isinstance(default, dict):
d51a18e5b0e3 Reimplement configmix.safe_merge() do to a deepcopy of all source configurations when merging.
Franz Glasner <hg@dom66.de>
parents: 110
diff changeset
395 for k, v in default.items():
144
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
396 if filter_comments and _is_comment(k):
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
397 continue
111
d51a18e5b0e3 Reimplement configmix.safe_merge() do to a deepcopy of all source configurations when merging.
Franz Glasner <hg@dom66.de>
parents: 110
diff changeset
398 if k not in user:
d51a18e5b0e3 Reimplement configmix.safe_merge() do to a deepcopy of all source configurations when merging.
Franz Glasner <hg@dom66.de>
parents: 110
diff changeset
399 user[k] = copy.deepcopy(v)
d51a18e5b0e3 Reimplement configmix.safe_merge() do to a deepcopy of all source configurations when merging.
Franz Glasner <hg@dom66.de>
parents: 110
diff changeset
400 else:
144
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
401 user[k] = _safe_merge(user[k], v, filter_comments)
111
d51a18e5b0e3 Reimplement configmix.safe_merge() do to a deepcopy of all source configurations when merging.
Franz Glasner <hg@dom66.de>
parents: 110
diff changeset
402 return user
139
c87b0dc54e1d Allow custom configuration filename extensions and custom loaders that can handle custom configuration file syntax styles
Franz Glasner <hg@dom66.de>
parents: 138
diff changeset
403
c87b0dc54e1d Allow custom configuration filename extensions and custom loaders that can handle custom configuration file syntax styles
Franz Glasner <hg@dom66.de>
parents: 138
diff changeset
404
144
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
405 def _filter_comments(d):
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
406 """Recursively filter comments keys in the dict `d`.
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
407
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
408 Comment keys are keys that start with any of the items in
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
409 :data:`COMMENTS`.
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
410
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
411 """
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
412 if not isinstance(d, dict):
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
413 return
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
414 # use a copy of the keys because we change `d` while iterating
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
415 for k in list(d.keys()):
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
416 if _is_comment(k):
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
417 del d[k]
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
418 else:
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
419 if isinstance(d[k], dict):
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
420 _filter_comments(d[k])
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
421
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
422
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
423 def _is_comment(k):
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
424 for i in COMMENTS:
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
425 if k.startswith(i):
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
426 return True
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
427 return False
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
428
7e6ec99d5ff5 Allow comments as keys and filter them by default
Franz Glasner <hg@dom66.de>
parents: 141
diff changeset
429
139
c87b0dc54e1d Allow custom configuration filename extensions and custom loaders that can handle custom configuration file syntax styles
Franz Glasner <hg@dom66.de>
parents: 138
diff changeset
430 #
178
eeb3ed104ea1 Begin refactoring the associations between filename extensions and loader functions:
Franz Glasner <fzglas.hg@dom66.de>
parents: 177
diff changeset
431 # Init loader defaults: mode->loader and extension->mode
139
c87b0dc54e1d Allow custom configuration filename extensions and custom loaders that can handle custom configuration file syntax styles
Franz Glasner <hg@dom66.de>
parents: 138
diff changeset
432 #
189
0d0980ed74cc Rename the "_mode_loaders" variable to "mode_loaders" and make is therefore a "public" item
Franz Glasner <fzglas.hg@dom66.de>
parents: 188
diff changeset
433 mode_loaders.update(DEFAULT_MODE_LOADERS)
181
7cfdc972af42 Refactor: Renamed public functions to be conform with the new loader search
Franz Glasner <fzglas.hg@dom66.de>
parents: 180
diff changeset
434 for _pattern, _mode in DEFAULT_ASSOC:
7cfdc972af42 Refactor: Renamed public functions to be conform with the new loader search
Franz Glasner <fzglas.hg@dom66.de>
parents: 180
diff changeset
435 set_assoc(_pattern, _mode)