Mercurial > hgrepos > Python > libs > ConfigMix
comparison mixconfig/ini.py @ 2:9981a68040b6
An INI-style configuration file parser
| author | Franz Glasner <f.glasner@feldmann-mg.com> |
|---|---|
| date | Tue, 08 Mar 2016 15:40:37 +0100 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:e4c63b4f1568 | 2:9981a68040b6 |
|---|---|
| 1 # -*- coding: utf-8 -*- | |
| 2 | |
| 3 from __future__ import division, absolute_import, print_function | |
| 4 | |
| 5 import sys | |
| 6 import os | |
| 7 import io | |
| 8 import locale | |
| 9 try: | |
| 10 from configparser import SafeConfigParser, NoSectionError, NoOptionError | |
| 11 except ImportError: | |
| 12 from ConfigParser import SafeConfigParser, NoSectionError, NoOptionError | |
| 13 | |
| 14 from .compat import PY2 | |
| 15 | |
| 16 | |
| 17 __all__ = ["INIConfigParser", "NoSectionError", "NoOptionError"] | |
| 18 | |
| 19 | |
| 20 class INIConfigParser(SafeConfigParser): | |
| 21 | |
| 22 """A case sensitive config parser that returns all-unicode string | |
| 23 values. | |
| 24 | |
| 25 """ | |
| 26 | |
| 27 def __init__(self, filename, executable=None, encoding=None): | |
| 28 SafeConfigParser.__init__(self) | |
| 29 if executable is None: | |
| 30 executable = sys.argv[0] | |
| 31 if PY2: | |
| 32 if isinstance(filename, str): | |
| 33 filename = filename.decode(locale.getpreferredencoding()) | |
| 34 if isinstance(executable, str): | |
| 35 executable = executable.decode(locale.getpreferredencoding()) | |
| 36 self.executable = os.path.normpath(os.path.abspath(executable)) | |
| 37 if encoding is None: | |
| 38 encoding = locale.getpreferredencoding() | |
| 39 self.encoding = encoding | |
| 40 with io.open(filename, | |
| 41 mode="rt", | |
| 42 encoding=self.encoding) as cf: | |
| 43 self.readfp(cf, filename) | |
| 44 | |
| 45 def optionxform(self, option): | |
| 46 return option | |
| 47 | |
| 48 def get_path_list(self, section, option): | |
| 49 v = self.get(section, option) | |
| 50 return v.split(os.pathsep) | |
| 51 | |
| 52 def read(self, filenames): | |
| 53 raise NotImplementedError("use `readfp()' instead") | |
| 54 | |
| 55 def readfp(self, fp, filename): | |
| 56 if hasattr(self, "filename"): | |
| 57 raise RuntimeError("already initialized") | |
| 58 filename = os.path.normpath(os.path.abspath(filename)) | |
| 59 if PY2: | |
| 60 if isinstance(filename, str): | |
| 61 filename = filename.decode(locale.getpreferredencoding()) | |
| 62 self.set(None, "self", filename) | |
| 63 self.set(None, "here", os.path.dirname(filename)) | |
| 64 self.set(None, "root", os.path.dirname(self.executable)) | |
| 65 SafeConfigParser.readfp(self, fp, filename=filename) | |
| 66 self.filename = filename | |
| 67 self.root = os.path.dirname(self.executable) | |
| 68 | |
| 69 def getx(self, section, option): | |
| 70 """Extended get() with some automatic type conversion support. | |
| 71 | |
| 72 Default: Fetch as string (like `get()`). | |
| 73 | |
| 74 If annotated with ``:bool:`` fetch as bool, if annotated with | |
| 75 ``:int:`` fetch as int, if annotated with ``:float:`` fetch as | |
| 76 float. | |
| 77 | |
| 78 """ | |
| 79 v = self.get(section, option) | |
| 80 if v.startswith(":bool:"): | |
| 81 v = v[6:].lower() | |
| 82 if v not in self._BOOL_CVT: | |
| 83 raise ValueError("Not a boolean: %s" % (v, )) | |
| 84 return self._BOOL_CVT[v] | |
| 85 elif v.startswith(":int:"): | |
| 86 return int(v[5:], 0) | |
| 87 elif v.startswith(":float:"): | |
| 88 return float(v[7:]) | |
| 89 else: | |
| 90 return v | |
| 91 | |
| 92 _BOOL_CVT = {'1': True, 'yes': True, 'true': True, 'on': True, | |
| 93 '0': False, 'no': False, 'false': False, 'off': False} |
