annotate configmix/__init__.py @ 141:647782859ae1

An extra hint that filename extension comparisons for loader lookup are case-insensitive
author Franz Glasner <hg@dom66.de>
date Sat, 07 Apr 2018 09:24:20 +0200
parents c87b0dc54e1d
children 7e6ec99d5ff5
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
84
6b6acc50a19d Remove duplicate "Copyright" output
Franz Glasner <hg@dom66.de>
parents: 82
diff changeset
5 :Copyright: (c) 2015–2018, 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.
6216c561532a Put a Copyright and License notice into the package's __init__.py
Franz Glasner <hg@dom66.de>
parents: 69
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
96
778c3bb1fb41 Bump development version to 0.6.0.dev1
Franz Glasner <hg@dom66.de>
parents: 85
diff changeset
16 __version__ = "0.6.0.dev1"
0
53ea2bc254e7 Begin a package to abstract some of the important configuration handling stuff.
Franz Glasner <hg@dom66.de>
parents:
diff changeset
17
52
6c7f90dbce98 Adjusted the Copyright and change the RCS keywords in accordance with "kwarchive"
Franz Glasner <hg@dom66.de>
parents: 45
diff changeset
18 __revision__ = "$Revision$"
6c7f90dbce98 Adjusted the Copyright and change the RCS keywords in accordance with "kwarchive"
Franz Glasner <hg@dom66.de>
parents: 45
diff changeset
19
0
53ea2bc254e7 Begin a package to abstract some of the important configuration handling stuff.
Franz Glasner <hg@dom66.de>
parents:
diff changeset
20
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
21 import copy
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
22
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
23 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
24
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
25
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
26 __all__ = ["load", "safe_load",
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
27 "set_loader", "default_loaders",
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
28 "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
29
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
30
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
31 def load(*files):
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
32 """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
33 and return the resulting configuration dictionary.
2196362c0467 Enhance documentation of "configmix.load()"
Franz Glasner <hg@dom66.de>
parents: 107
diff changeset
34
2196362c0467 Enhance documentation of "configmix.load()"
Franz Glasner <hg@dom66.de>
parents: 107
diff changeset
35 :param files: the filenames of the configuration files to read and merge
2196362c0467 Enhance documentation of "configmix.load()"
Franz Glasner <hg@dom66.de>
parents: 107
diff changeset
36 :returns: the configuration
2196362c0467 Enhance documentation of "configmix.load()"
Franz Glasner <hg@dom66.de>
parents: 107
diff changeset
37 :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
38
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
39 """
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
40 if not files:
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
41 return Configuration()
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
42 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
43 ex = merge(None, _load_cfg_from_file(files[0]))
107
2ee042791197 Don't read the first configuration file a second time.
Franz Glasner <hg@dom66.de>
parents: 98
diff changeset
44 for f in files[1:]:
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
45 ex = merge(_load_cfg_from_file(f), ex)
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
46 return Configuration(ex)
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
47
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
112
c50ad93eb5dc Implemented a "safe_load()" to load with safe merging
Franz Glasner <hg@dom66.de>
parents: 111
diff changeset
49 def safe_load(*files):
c50ad93eb5dc Implemented a "safe_load()" to load with safe merging
Franz Glasner <hg@dom66.de>
parents: 111
diff changeset
50 """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
51 instead of :func:`merge`
c50ad93eb5dc Implemented a "safe_load()" to load with safe merging
Franz Glasner <hg@dom66.de>
parents: 111
diff changeset
52
c50ad93eb5dc Implemented a "safe_load()" to load with safe merging
Franz Glasner <hg@dom66.de>
parents: 111
diff changeset
53 """
c50ad93eb5dc Implemented a "safe_load()" to load with safe merging
Franz Glasner <hg@dom66.de>
parents: 111
diff changeset
54 if not files:
c50ad93eb5dc Implemented a "safe_load()" to load with safe merging
Franz Glasner <hg@dom66.de>
parents: 111
diff changeset
55 return Configuration()
c50ad93eb5dc Implemented a "safe_load()" to load with safe merging
Franz Glasner <hg@dom66.de>
parents: 111
diff changeset
56 else:
c50ad93eb5dc Implemented a "safe_load()" to load with safe merging
Franz Glasner <hg@dom66.de>
parents: 111
diff changeset
57 ex = safe_merge(None, _load_cfg_from_file(files[0]))
c50ad93eb5dc Implemented a "safe_load()" to load with safe merging
Franz Glasner <hg@dom66.de>
parents: 111
diff changeset
58 for f in files[1:]:
c50ad93eb5dc Implemented a "safe_load()" to load with safe merging
Franz Glasner <hg@dom66.de>
parents: 111
diff changeset
59 ex = safe_merge(_load_cfg_from_file(f), ex)
c50ad93eb5dc Implemented a "safe_load()" to load with safe merging
Franz Glasner <hg@dom66.de>
parents: 111
diff changeset
60 return Configuration(ex)
c50ad93eb5dc Implemented a "safe_load()" to load with safe merging
Franz Glasner <hg@dom66.de>
parents: 111
diff changeset
61
c50ad93eb5dc Implemented a "safe_load()" to load with safe merging
Franz Glasner <hg@dom66.de>
parents: 111
diff changeset
62
138
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
63 def _load_yaml(filename):
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
64 from . import yaml
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
65 with open(filename, "rb") as yf:
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
66 return yaml.safe_load(yf)
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
67
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
68
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
69 def _load_json(filename):
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
70 from . import json
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
71 return json.load(filename)
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
72
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
73
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
74 def _load_py(filename):
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
75 from . import py
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
76 return py.load(filename)
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
77
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
78
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
79 def _load_ini(filename):
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
80 from . import ini
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
81 return ini.load(filename)
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
82
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
83
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
84 default_loaders = {
138
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
85 ".yml": _load_yaml,
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
86 ".yaml": _load_yaml,
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
87 ".json": _load_json,
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
88 ".py": _load_py,
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
89 ".ini": _load_ini
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
90 }
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
91 """The builtin default associations of extensions with loaders"""
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
92
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
93
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
94 DEFAULT_LOADER = object()
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
95 """Marker for the default loader for an extension.
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
96
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
97 To be used in :func:`set_loader`.
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
98 """
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
99
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
100 _loaders = {}
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
101 """All configured loader functions"""
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
102
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
103
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
104 def clear_loader():
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
105 """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
106
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
107 The :data:`default_loaders` are **not** changed.
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
108
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
109 """
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
110 _loaders.clear()
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
111
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
112
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
113 def set_loader(extension, loader):
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
114 """Associate a filename trailer `extension` with a callable `loader` that
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
115 will be called when :func:`load` encounters a file argument that ends
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
116 with `extension`.
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
117
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
118 :param str extension: the extension to associate a loader with
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
119 :param callable loader: a callable that accepts a `filename` argument and
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
120 returns a parsed configuration from a given file
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
121
141
647782859ae1 An extra hint that filename extension comparisons for loader lookup are case-insensitive
Franz Glasner <hg@dom66.de>
parents: 139
diff changeset
122 `extension` should be all lowercase because lookup in the loader database
647782859ae1 An extra hint that filename extension comparisons for loader lookup are case-insensitive
Franz Glasner <hg@dom66.de>
parents: 139
diff changeset
123 is *case-insensitive*.
647782859ae1 An extra hint that filename extension comparisons for loader lookup are case-insensitive
Franz Glasner <hg@dom66.de>
parents: 139
diff changeset
124
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
125 If `loader` is :data:`DEFAULT_LOADER` then the default association
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
126 from :data:`default_loaders` will be used -- if any.
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
127
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
128 """
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
129 if loader is DEFAULT_LOADER:
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
130 try:
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
131 _loaders[extension] = default_loaders[extension]
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
132 except KeyError:
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
133 raise ValueError("no DEFAULT loader for extension: %r" % extension)
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
134 else:
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
135 _loaders[extension] = loader
138
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
136
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
137
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
138 def _load_cfg_from_file(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
139 fnl = filename.lower()
138
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
140 extensions = list(_loaders.keys())
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
141 extensions.sort(key=lambda x: len(x), reverse=True)
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
142 for ext in extensions:
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
143 if fnl.endswith(ext):
b883f4ef1967 Indirectly map extensions to configuration file styles
Franz Glasner <hg@dom66.de>
parents: 122
diff changeset
144 return _loaders[ext](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
145 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
146 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
147 "%r" % filename)
8
7090c295c940 Two differend tree merge function implementations: not yet finished
Franz Glasner <hg@dom66.de>
parents: 5
diff changeset
148
7090c295c940 Two differend tree merge function implementations: not yet finished
Franz Glasner <hg@dom66.de>
parents: 5
diff changeset
149
11
aecb36d4025f Deactivate the "dict_merge()" function from yconfig
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 10
diff changeset
150 if 0:
aecb36d4025f Deactivate the "dict_merge()" function from yconfig
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 10
diff changeset
151 #
aecb36d4025f Deactivate the "dict_merge()" function from yconfig
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 10
diff changeset
152 # 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
153 # License: BSD License
aecb36d4025f Deactivate the "dict_merge()" function from yconfig
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 10
diff changeset
154 #
aecb36d4025f Deactivate the "dict_merge()" function from yconfig
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 10
diff changeset
155 def dict_merge(a, b):
aecb36d4025f Deactivate the "dict_merge()" function from yconfig
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 10
diff changeset
156 """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
157 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
158 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
159
11
aecb36d4025f Deactivate the "dict_merge()" function from yconfig
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 10
diff changeset
160 if not isinstance(b, dict):
aecb36d4025f Deactivate the "dict_merge()" function from yconfig
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 10
diff changeset
161 return b
aecb36d4025f Deactivate the "dict_merge()" function from yconfig
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 10
diff changeset
162 result = deepcopy(a)
aecb36d4025f Deactivate the "dict_merge()" function from yconfig
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 10
diff changeset
163 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
164 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
165 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
166 else:
aecb36d4025f Deactivate the "dict_merge()" function from yconfig
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 10
diff changeset
167 result[k] = deepcopy(v)
aecb36d4025f Deactivate the "dict_merge()" function from yconfig
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 10
diff changeset
168 return result
8
7090c295c940 Two differend tree merge function implementations: not yet finished
Franz Glasner <hg@dom66.de>
parents: 5
diff changeset
169
7090c295c940 Two differend tree merge function implementations: not yet finished
Franz Glasner <hg@dom66.de>
parents: 5
diff changeset
170
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
171 def merge(user, 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
172 """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
173
d6ba53ce2091 Better documentation of the core function in "configmix"
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 96
diff changeset
174 :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
175 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
176 into `default`
98
d6ba53ce2091 Better documentation of the core function in "configmix"
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 96
diff changeset
177 :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
178 the base configuration where `user` is logically merged into
29cf359ddf4d Remove the "_first" parameter from "merge" and "safe_merge" by splitting into two functions
Franz Glasner <hg@dom66.de>
parents: 108
diff changeset
179 :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
180 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
181
29cf359ddf4d Remove the "_first" parameter from "merge" and "safe_merge" by splitting into two functions
Franz Glasner <hg@dom66.de>
parents: 108
diff changeset
182 .. note:: The configuration in `default` is not changed but the
29cf359ddf4d Remove the "_first" parameter from "merge" and "safe_merge" by splitting into two functions
Franz Glasner <hg@dom66.de>
parents: 108
diff changeset
183 configuration given in `user` is changed **inplace**.
8
7090c295c940 Two differend tree merge function implementations: not yet finished
Franz Glasner <hg@dom66.de>
parents: 5
diff changeset
184
7090c295c940 Two differend tree merge function implementations: not yet finished
Franz Glasner <hg@dom66.de>
parents: 5
diff changeset
185 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
186
7090c295c940 Two differend tree merge function implementations: not yet finished
Franz Glasner <hg@dom66.de>
parents: 5
diff changeset
187 """
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
188 if user is None:
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
189 return default
8
7090c295c940 Two differend tree merge function implementations: not yet finished
Franz Glasner <hg@dom66.de>
parents: 5
diff changeset
190 if isinstance(user, dict) and isinstance(default, dict):
9
6835a5663008 FIX: Style
Franz Glasner <f.glasner@feldmann-mg.com>
parents: 8
diff changeset
191 for k, v in default.items():
8
7090c295c940 Two differend tree merge function implementations: not yet finished
Franz Glasner <hg@dom66.de>
parents: 5
diff changeset
192 if k not in user:
7090c295c940 Two differend tree merge function implementations: not yet finished
Franz Glasner <hg@dom66.de>
parents: 5
diff changeset
193 user[k] = v
7090c295c940 Two differend tree merge function implementations: not yet finished
Franz Glasner <hg@dom66.de>
parents: 5
diff changeset
194 else:
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
195 user[k] = _merge(user[k], v)
8
7090c295c940 Two differend tree merge function implementations: not yet finished
Franz Glasner <hg@dom66.de>
parents: 5
diff changeset
196 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
197
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
198
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
199 def _merge(user, 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
200 """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
201
29cf359ddf4d Remove the "_first" parameter from "merge" and "safe_merge" by splitting into two functions
Franz Glasner <hg@dom66.de>
parents: 108
diff changeset
202 """
29cf359ddf4d Remove the "_first" parameter from "merge" and "safe_merge" by splitting into two functions
Franz Glasner <hg@dom66.de>
parents: 108
diff changeset
203 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
204 for k, v in default.items():
29cf359ddf4d Remove the "_first" parameter from "merge" and "safe_merge" by splitting into two functions
Franz Glasner <hg@dom66.de>
parents: 108
diff changeset
205 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
206 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
207 else:
29cf359ddf4d Remove the "_first" parameter from "merge" and "safe_merge" by splitting into two functions
Franz Glasner <hg@dom66.de>
parents: 108
diff changeset
208 user[k] = _merge(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
209 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
210
29cf359ddf4d Remove the "_first" parameter from "merge" and "safe_merge" by splitting into two functions
Franz Glasner <hg@dom66.de>
parents: 108
diff changeset
211
29cf359ddf4d Remove the "_first" parameter from "merge" and "safe_merge" by splitting into two functions
Franz Glasner <hg@dom66.de>
parents: 108
diff changeset
212 def safe_merge(user, 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
213 """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
214 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
215
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
216 No given argument is ever changed inplace. Every object from `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
217 is decoupled from the result -- so changing the `default` configuration
d51a18e5b0e3 Reimplement configmix.safe_merge() do to a deepcopy of all source configurations when merging.
Franz Glasner <hg@dom66.de>
parents: 110
diff changeset
218 lates does not yield into a merged configuration later.
d51a18e5b0e3 Reimplement configmix.safe_merge() do to a deepcopy of all source configurations when merging.
Franz Glasner <hg@dom66.de>
parents: 110
diff changeset
219
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
220 """
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
221 if user is None:
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
222 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
223 user = copy.deepcopy(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
224 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
225 for k, v in default.items():
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
226 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
227 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
228 else:
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
229 user[k] = _safe_merge(user[k], 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
230 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
231
d51a18e5b0e3 Reimplement configmix.safe_merge() do to a deepcopy of all source configurations when merging.
Franz Glasner <hg@dom66.de>
parents: 110
diff changeset
232
d51a18e5b0e3 Reimplement configmix.safe_merge() do to a deepcopy of all source configurations when merging.
Franz Glasner <hg@dom66.de>
parents: 110
diff changeset
233 def _safe_merge(user, 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
234 """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
235
d51a18e5b0e3 Reimplement configmix.safe_merge() do to a deepcopy of all source configurations when merging.
Franz Glasner <hg@dom66.de>
parents: 110
diff changeset
236 """
d51a18e5b0e3 Reimplement configmix.safe_merge() do to a deepcopy of all source configurations when merging.
Franz Glasner <hg@dom66.de>
parents: 110
diff changeset
237 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
238 for k, v in default.items():
d51a18e5b0e3 Reimplement configmix.safe_merge() do to a deepcopy of all source configurations when merging.
Franz Glasner <hg@dom66.de>
parents: 110
diff changeset
239 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
240 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
241 else:
d51a18e5b0e3 Reimplement configmix.safe_merge() do to a deepcopy of all source configurations when merging.
Franz Glasner <hg@dom66.de>
parents: 110
diff changeset
242 user[k] = _safe_merge(user[k], 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
243 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
244
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
245
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
246 #
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
247 # Init loader defaults
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
248 #
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
249 for _extension in default_loaders:
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
250 set_loader(_extension, DEFAULT_LOADER)