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}