1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 """
16 Functions for doing data persistence with ConfigObj.
17
18 It requires access to the validate module and ConfigObj.
19 """
20
21 __version__ = '0.1.0'
22
23 __all__ = (
24 'add_configspec',
25 'write_configspec',
26 'add_typeinfo',
27 'typeinfo_to_configspec',
28 'vtor',
29 'store',
30 'restore',
31 'save_configspec',
32 '__version__'
33 )
34
35 from configobj import ConfigObj
36
37 try:
38 from validate import Validator
39 except ImportError:
40 vtor = None
41 else:
42 vtor = Validator()
43
45 """
46 A function that adds a configspec to a ConfigObj.
47
48 Will only work for ConfigObj instances using basic datatypes :
49
50 * floats
51 * strings
52 * ints
53 * booleans
54 * Lists of the above
55 """
56 config.configspec = {}
57 for entry in config:
58 val = config[entry]
59 if isinstance(val, dict):
60
61 add_configspec(val)
62 elif isinstance(val, bool):
63 config.configspec[entry] = 'boolean'
64 elif isinstance(val, int):
65 config.configspec[entry] = 'integer'
66 elif isinstance(val, float):
67 config.configspec[entry] = 'float'
68 elif isinstance(val, str):
69 config.configspec[entry] = 'string'
70 elif isinstance(val, (list, tuple)):
71 list_type = None
72 out_list = []
73 for mem in val:
74 if isinstance(mem, str):
75 this = 'string'
76 elif isinstance(mem, bool):
77 this = 'boolean'
78 elif isinstance(mem, int):
79 this = 'integer'
80 elif isinstance(mem, float):
81 this = 'float'
82 else:
83 raise TypeError('List member "%s" is an innapropriate type.' % mem)
84 if list_type and this != list_type:
85 list_type = 'mixed'
86 elif list_type is None:
87 list_type = this
88 out_list.append(this)
89 if list_type is None:
90 l = 'list(%s)'
91 else:
92 list_type = {'integer': 'int', 'boolean': 'bool',
93 'mixed': 'mixed', 'float': 'float',
94 'string': 'string' }[list_type]
95 l = '%s_list(%%s)' % list_type
96 config.configspec[entry] = l % str(out_list)[1:-1]
97
98 else:
99 raise TypeError('Value "%s" is an innapropriate type.' % val)
100
102 """Return the configspec (of a ConfigObj) as a list of lines."""
103 out = []
104 for entry in config:
105 val = config[entry]
106 if isinstance(val, dict):
107
108 m = config.main._write_marker('', val.depth, entry, '')
109 out.append(m)
110 out += write_configspec(val)
111 else:
112 name = config.main._quote(entry, multiline=False)
113 out.append("%s = %s" % (name, config.configspec[entry]))
114
115 return out
116
118 """
119 Turns the configspec attribute of each section into a member of the
120 section. (Called ``__types__``).
121
122 You must have already called ``add_configspec`` on the ConfigObj.
123 """
124 for entry in config.sections:
125 add_typeinfo(config[entry])
126 config['__types__'] = config.configspec
127
129 """Turns the '__types__' member of each section into a configspec."""
130 for entry in config.sections:
131 if entry == '__types__':
132 continue
133 typeinfo_to_configspec(config[entry])
134 config.configspec = config['__types__']
135 del config['__types__']
136
138 """"
139 Passed a ConfigObj instance add type info and save.
140
141 Returns the result of calling ``config.write()``.
142 """
143 add_configspec(config)
144 add_typeinfo(config)
145 return config.write()
146
148 """
149 Restore a ConfigObj saved using the ``store`` function.
150
151 Takes a filename or list of lines, returns the ConfigObj instance.
152
153 Uses the built-in Validator instance of this module (vtor).
154
155 Raises an ImportError if the validate module isn't available
156 """
157 if vtor is None:
158 raise ImportError('Failed to import the validate module.')
159 config = ConfigObj(stored)
160 typeinfo_to_configspec(config)
161 config.validate(vtor)
162 return config
163
168
170 """
171 A dummy function for the sake of doctest.
172
173 First test add_configspec
174 >>> from configobj import ConfigObj
175 >>> from validate import Validator
176 >>> vtor = Validator()
177 >>> config = ConfigObj()
178 >>> config['member 1'] = 3
179 >>> config['member 2'] = 3.0
180 >>> config['member 3'] = True
181 >>> config['member 4'] = [3, 3.0, True]
182 >>> add_configspec(config)
183 >>> assert config.configspec == { 'member 2': 'float',
184 ... 'member 3': 'boolean', 'member 1': 'integer',
185 ... 'member 4': "mixed_list('integer', 'float', 'boolean')"}
186 >>> assert config.validate(vtor) == True
187
188 Next test write_configspec - including a nested section
189 >>> config['section 1'] = config.copy()
190 >>> add_configspec(config)
191 >>> a = config.write()
192 >>> configspec = write_configspec(config)
193 >>> b = ConfigObj(a, configspec=configspec)
194 >>> assert b.validate(vtor) == True
195 >>> assert b == config
196
197 Next test add_typeinfo and typeinfo_to_configspec
198 >>> orig = ConfigObj(config)
199 >>> add_typeinfo(config)
200 >>> a = ConfigObj(config.write())
201 >>> typeinfo_to_configspec(a)
202 >>> assert a.validate(vtor) == True
203 >>> assert a == orig
204 >>> typeinfo_to_configspec(config)
205 >>> assert config.validate(vtor) == True
206 >>> assert config == orig
207
208 Test store and restore
209 >>> a = store(config)
210 >>> b = restore(a)
211 >>> assert b == orig
212
213 Test save_configspec
214 >>> a = save_configspec(orig)
215 >>> b = ConfigObj(b, configspec=a)
216 >>> b.validate(vtor)
217 1
218 """
219
220 if __name__ == '__main__':
221
222
223 import doctest
224 doctest.testmod()
225
226 """
227 ISSUES
228 ======
229
230 TODO
231 ====
232
233
234 CHANGELOG
235 =========
236
237 2005/09/07
238 ----------
239
240 Module created.
241
242 """
243