58 option is not configured in a ini-like configuration file. |
58 option is not configured in a ini-like configuration file. |
59 |
59 |
60 `set()` differs from `RawConfigParser`'s `set()` method. `set()` |
60 `set()` differs from `RawConfigParser`'s `set()` method. `set()` |
61 takes the `section` and `option` arguments combined to a single |
61 takes the `section` and `option` arguments combined to a single |
62 string in the form "section.option". |
62 string in the form "section.option". |
63 |
|
64 """ |
63 """ |
65 |
64 |
66 def __init__(self): |
65 def __init__(self): |
67 RawConfigParser.__init__(self) |
66 RawConfigParser.__init__(self) |
68 self._modified = False |
67 self._modified = False |
96 For a boolean True, the value must be set to '1', 'on', 'yes', |
95 For a boolean True, the value must be set to '1', 'on', 'yes', |
97 'true' or True. For a boolean False, the value must set to '0', |
96 'true' or True. For a boolean False, the value must set to '0', |
98 'off', 'no', 'false' or False. |
97 'off', 'no', 'false' or False. |
99 If the option has another value assigned this method will raise |
98 If the option has another value assigned this method will raise |
100 a ValueError. |
99 a ValueError. |
101 |
|
102 """ |
100 """ |
103 # if the setting was modified it may be still a boolean value lets see |
101 # if the setting was modified it may be still a boolean value lets see |
104 tmp = self.get(section, option) |
102 tmp = self.get(section, option) |
105 if isinstance(tmp, bool): |
103 if isinstance(tmp, bool): |
106 return tmp |
104 return tmp |
136 return sect_opt |
133 return sect_opt |
137 |
134 |
138 def items(self, section): |
135 def items(self, section): |
139 """returns an iterable that returns key, value ``tuples`` from |
136 """returns an iterable that returns key, value ``tuples`` from |
140 the given ``section``. |
137 the given ``section``. |
141 |
|
142 """ |
138 """ |
143 if section in self._sections: # check if the section was parsed |
139 if section in self._sections: # check if the section was parsed |
144 sect = self._sections[section] |
140 sect = self._sections[section] |
145 elif not section in self._cfg: |
141 elif not section in self._cfg: |
146 raise NoSectionError(section) |
142 raise NoSectionError(section) |
167 `option` : string |
163 `option` : string |
168 the configuration option in the form "section.option" |
164 the configuration option in the form "section.option" |
169 |
165 |
170 Throws a `NoDefaultError`, if no default value was passed to |
166 Throws a `NoDefaultError`, if no default value was passed to |
171 `LazyConfigOption.__init__()` for the `option`. |
167 `LazyConfigOption.__init__()` for the `option`. |
172 |
|
173 """ |
168 """ |
174 section, option = self._get_section_option(option) |
169 section, option = self._get_section_option(option) |
175 try: |
170 try: |
176 return self._cfg[section][option].getter(section, option) |
171 return self._cfg[section][option].getter(section, option) |
177 except (NoSectionError, NoOptionError): |
172 except (NoSectionError, NoOptionError): |
188 def set(self, option, value): |
183 def set(self, option, value): |
189 """Set the `value` of the `option`. |
184 """Set the `value` of the `option`. |
190 |
185 |
191 Throws a `ValueError` if `value` couldn't be converted using |
186 Throws a `ValueError` if `value` couldn't be converted using |
192 `LazyConfigOption.cls`. |
187 `LazyConfigOption.cls`. |
193 |
188 """ |
194 """ |
189 # pylint: disable=W0221 |
195 # pylint: disable-msg=W0221 |
|
196 # @pylint: _L A Z Y_ |
190 # @pylint: _L A Z Y_ |
197 section, option = self._get_section_option(option) |
191 section, option = self._get_section_option(option) |
198 val = self._cfg[section][option].cls(value) |
192 val = self._cfg[section][option].cls(value) |
199 if self._cfg[section][option].validate: |
193 if self._cfg[section][option].validate: |
200 val = self._cfg[section][option].validate(val) |
194 val = self._cfg[section][option].validate(val) |
208 return section.lower() in self._cfg |
202 return section.lower() in self._cfg |
209 |
203 |
210 def has_option(self, option): |
204 def has_option(self, option): |
211 """Checks if the option (section.option) is a known |
205 """Checks if the option (section.option) is a known |
212 configuration option. |
206 configuration option. |
213 |
207 """ |
214 """ |
208 # pylint: disable=W0221 |
215 # pylint: disable-msg=W0221 |
|
216 # @pylint: _L A Z Y_ |
209 # @pylint: _L A Z Y_ |
217 try: |
210 try: |
218 self._get_section_option(option) |
211 self._get_section_option(option) |
219 return True |
212 return True |
220 except(BadOptionError, NoSectionError, NoOptionError): |
213 except(BadOptionError, NoSectionError, NoOptionError): |
229 """A simple container class for configuration settings. |
222 """A simple container class for configuration settings. |
230 |
223 |
231 `LazyConfigOption` instances are required by `LazyConfig` instances, |
224 `LazyConfigOption` instances are required by `LazyConfig` instances, |
232 and instances of classes derived from `LazyConfig`, like the |
225 and instances of classes derived from `LazyConfig`, like the |
233 `Config` class. |
226 `Config` class. |
234 |
|
235 """ |
227 """ |
236 __slots__ = ('__cls', '__default', '__getter', '__validate') |
228 __slots__ = ('__cls', '__default', '__getter', '__validate') |
237 |
229 |
238 def __init__(self, cls, default, getter, validate=None): |
230 def __init__(self, cls, default, getter, validate=None): |
239 """Creates a new `LazyConfigOption` instance. |
231 """Creates a new `LazyConfigOption` instance. |
249 A method's name of `RawConfigParser` and derived classes, to |
241 A method's name of `RawConfigParser` and derived classes, to |
250 get a option's value, e.g. `self.getint`. |
242 get a option's value, e.g. `self.getint`. |
251 `validate` : NoneType or a callable |
243 `validate` : NoneType or a callable |
252 None or any method, that takes one argument, in order to |
244 None or any method, that takes one argument, in order to |
253 check the value, when `LazyConfig.set()` is called. |
245 check the value, when `LazyConfig.set()` is called. |
254 |
|
255 """ |
246 """ |
256 self.__cls = cls |
247 self.__cls = cls |
257 if not default is None: # enforce the type of the default value |
248 if not default is None: # enforce the type of the default value |
258 self.__default = self.__cls(default) |
249 self.__default = self.__cls(default) |
259 else: |
250 else: |
267 validate.__class__.__name__) |
258 validate.__class__.__name__) |
268 self.__validate = validate |
259 self.__validate = validate |
269 |
260 |
270 @property |
261 @property |
271 def cls(self): |
262 def cls(self): |
272 """The class of the option's value e.g. `str`, `unicode` or |
263 """The class of the option's value e.g. `str`, `unicode` or `bool`.""" |
273 `bool`. |
|
274 |
|
275 """ |
|
276 return self.__cls |
264 return self.__cls |
277 |
265 |
278 @property |
266 @property |
279 def default(self): |
267 def default(self): |
280 """The option's default value, may be `None`""" |
268 """The option's default value, may be `None`""" |
339 'delete_directory': LCO(bool_t, False, self.getboolean), |
326 'delete_directory': LCO(bool_t, False, self.getboolean), |
340 'directory_mode': LCO(int, 504, self.getint), |
327 'directory_mode': LCO(int, 504, self.getint), |
341 'force_deletion': LCO(bool_t, False, self.getboolean), |
328 'force_deletion': LCO(bool_t, False, self.getboolean), |
342 }, |
329 }, |
343 'mailbox': { |
330 'mailbox': { |
344 'folders': LCO(str, 'Drafts:Sent:Templates:Trash', self.get), |
331 'folders': LCO(str, 'Drafts:Sent:Templates:Trash', |
|
332 self.unicode), |
345 'format': LCO(str, 'maildir', self.get, check_mailbox_format), |
333 'format': LCO(str, 'maildir', self.get, check_mailbox_format), |
346 'root': LCO(str, 'Maildir', self.get), |
334 'root': LCO(str, 'Maildir', self.unicode), |
347 }, |
335 }, |
348 'misc': { |
336 'misc': { |
349 'base_directory': LCO(str, '/srv/mail', self.get, is_dir), |
337 'base_directory': LCO(str, '/srv/mail', self.get, is_dir), |
350 'crypt_blowfish_rounds': LCO(int, 5, self.getint), |
338 'crypt_blowfish_rounds': LCO(int, 5, self.getint), |
351 'crypt_sha256_rounds': LCO(int, 5000, self.getint), |
339 'crypt_sha256_rounds': LCO(int, 5000, self.getint), |
361 def load(self): |
349 def load(self): |
362 """Loads the configuration, read only. |
350 """Loads the configuration, read only. |
363 |
351 |
364 Raises a ConfigError if the configuration syntax is |
352 Raises a ConfigError if the configuration syntax is |
365 invalid. |
353 invalid. |
366 |
|
367 """ |
354 """ |
368 try: |
355 try: |
369 self._cfg_file = open(self._cfg_filename, 'r') |
356 self._cfg_file = open(self._cfg_filename, 'r') |
370 self.readfp(self._cfg_file) |
357 self.readfp(self._cfg_file) |
371 except (MissingSectionHeaderError, ParsingError), err: |
358 except (MissingSectionHeaderError, ParsingError), err: |
408 def __chk_cfg(self): |
395 def __chk_cfg(self): |
409 """Checks all section's options for settings w/o a default |
396 """Checks all section's options for settings w/o a default |
410 value. |
397 value. |
411 |
398 |
412 Returns `True` if everything is fine, else `False`. |
399 Returns `True` if everything is fine, else `False`. |
413 |
|
414 """ |
400 """ |
415 errors = False |
401 errors = False |
416 for section in self._cfg.iterkeys(): |
402 for section in self._cfg.iterkeys(): |
417 missing = [] |
403 missing = [] |
418 for option, value in self._cfg[section].iteritems(): |
404 for option, value in self._cfg[section].iteritems(): |