bzr branch
http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1  | 
# configobj.py
 | 
2  | 
# A config file reader/writer that supports nested sections in config files.
 | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
3  | 
# Copyright (C) 2005-2008 Michael Foord, Nicola Larosa
 | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
4  | 
# E-mail: fuzzyman AT voidspace DOT org DOT uk
 | 
5  | 
#         nico AT tekNico DOT net
 | 
|
6  | 
||
7  | 
# ConfigObj 4
 | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
8  | 
# http://www.voidspace.org.uk/python/configobj.html
 | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
9  | 
|
10  | 
# Released subject to the BSD License
 | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
11  | 
# Please see http://www.voidspace.org.uk/python/license.shtml
 | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
12  | 
|
13  | 
# Scripts maintained at http://www.voidspace.org.uk/python/index.shtml
 | 
|
14  | 
# For information about bugfixes, updates and support, please join the
 | 
|
15  | 
# ConfigObj mailing list:
 | 
|
16  | 
# http://lists.sourceforge.net/lists/listinfo/configobj-develop
 | 
|
17  | 
# Comments, suggestions and bug reports welcome.
 | 
|
18  | 
||
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
19  | 
from __future__ import generators  | 
20  | 
||
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
21  | 
import sys  | 
22  | 
INTP_VER = sys.version_info[:2]  | 
|
23  | 
if INTP_VER < (2, 2):  | 
|
24  | 
raise RuntimeError("Python v.2.2 or later needed")  | 
|
25  | 
||
26  | 
import os, re  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
27  | 
compiler = None  | 
| 
3224.5.35
by Andrew Bennetts
 More improvements suggested by John's review.  | 
28  | 
# Bzr modification: Disabled import of 'compiler' module
 | 
29  | 
# bzr doesn't use the 'unrepr' feature of configobj, so importing compiler just
 | 
|
30  | 
# wastes several milliseconds on every single bzr invocation.
 | 
|
31  | 
#   -- Andrew Bennetts, 2008-10-14
 | 
|
32  | 
#try:
 | 
|
33  | 
#    import compiler
 | 
|
34  | 
#except ImportError:
 | 
|
35  | 
#    # for IronPython
 | 
|
36  | 
#    pass
 | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
37  | 
from types import StringTypes  | 
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
38  | 
from warnings import warn  | 
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
39  | 
try:  | 
40  | 
from codecs import BOM_UTF8, BOM_UTF16, BOM_UTF16_BE, BOM_UTF16_LE  | 
|
41  | 
except ImportError:  | 
|
42  | 
    # Python 2.2 does not have these
 | 
|
43  | 
    # UTF-8
 | 
|
44  | 
BOM_UTF8 = '\xef\xbb\xbf'  | 
|
45  | 
    # UTF-16, little endian
 | 
|
46  | 
BOM_UTF16_LE = '\xff\xfe'  | 
|
47  | 
    # UTF-16, big endian
 | 
|
48  | 
BOM_UTF16_BE = '\xfe\xff'  | 
|
49  | 
if sys.byteorder == 'little':  | 
|
50  | 
        # UTF-16, native endianness
 | 
|
51  | 
BOM_UTF16 = BOM_UTF16_LE  | 
|
52  | 
else:  | 
|
53  | 
        # UTF-16, native endianness
 | 
|
54  | 
BOM_UTF16 = BOM_UTF16_BE  | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
55  | 
|
56  | 
# A dictionary mapping BOM to
 | 
|
57  | 
# the encoding to decode with, and what to set the
 | 
|
58  | 
# encoding attribute to.
 | 
|
59  | 
BOMS = {  | 
|
60  | 
BOM_UTF8: ('utf_8', None),  | 
|
61  | 
BOM_UTF16_BE: ('utf16_be', 'utf_16'),  | 
|
62  | 
BOM_UTF16_LE: ('utf16_le', 'utf_16'),  | 
|
63  | 
BOM_UTF16: ('utf_16', 'utf_16'),  | 
|
64  | 
    }
 | 
|
65  | 
# All legal variants of the BOM codecs.
 | 
|
66  | 
# TODO: the list of aliases is not meant to be exhaustive, is there a
 | 
|
67  | 
#   better way ?
 | 
|
68  | 
BOM_LIST = {  | 
|
69  | 
'utf_16': 'utf_16',  | 
|
70  | 
'u16': 'utf_16',  | 
|
71  | 
'utf16': 'utf_16',  | 
|
72  | 
'utf-16': 'utf_16',  | 
|
73  | 
'utf16_be': 'utf16_be',  | 
|
74  | 
'utf_16_be': 'utf16_be',  | 
|
75  | 
'utf-16be': 'utf16_be',  | 
|
76  | 
'utf16_le': 'utf16_le',  | 
|
77  | 
'utf_16_le': 'utf16_le',  | 
|
78  | 
'utf-16le': 'utf16_le',  | 
|
79  | 
'utf_8': 'utf_8',  | 
|
80  | 
'u8': 'utf_8',  | 
|
81  | 
'utf': 'utf_8',  | 
|
82  | 
'utf8': 'utf_8',  | 
|
83  | 
'utf-8': 'utf_8',  | 
|
84  | 
    }
 | 
|
85  | 
||
86  | 
# Map of encodings to the BOM to write.
 | 
|
87  | 
BOM_SET = {  | 
|
88  | 
'utf_8': BOM_UTF8,  | 
|
89  | 
'utf_16': BOM_UTF16,  | 
|
90  | 
'utf16_be': BOM_UTF16_BE,  | 
|
91  | 
'utf16_le': BOM_UTF16_LE,  | 
|
92  | 
None: BOM_UTF8  | 
|
93  | 
    }
 | 
|
94  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
95  | 
|
96  | 
def match_utf8(encoding):  | 
|
97  | 
return BOM_LIST.get(encoding.lower()) == 'utf_8'  | 
|
98  | 
||
99  | 
||
100  | 
# Quote strings used for writing values
 | 
|
101  | 
squot = "'%s'"  | 
|
102  | 
dquot = '"%s"'  | 
|
103  | 
noquot = "%s"  | 
|
104  | 
wspace_plus = ' \r\t\n\v\t\'"'  | 
|
105  | 
tsquot = '"""%s"""'  | 
|
106  | 
tdquot = "'''%s'''"  | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
107  | 
|
108  | 
try:  | 
|
109  | 
    enumerate
 | 
|
110  | 
except NameError:  | 
|
111  | 
def enumerate(obj):  | 
|
112  | 
"""enumerate for Python 2.2."""  | 
|
113  | 
i = -1  | 
|
114  | 
for item in obj:  | 
|
115  | 
i += 1  | 
|
116  | 
yield i, item  | 
|
117  | 
||
118  | 
try:  | 
|
119  | 
True, False  | 
|
120  | 
except NameError:  | 
|
121  | 
True, False = 1, 0  | 
|
122  | 
||
123  | 
||
| 
3239.1.1
by Matt Nordhoff
 Upgrade ConfigObj to 4.5.2.  | 
124  | 
__version__ = '4.5.2'  | 
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
125  | 
|
126  | 
__revision__ = '$Id: configobj.py 156 2006-01-31 14:57:08Z fuzzyman $'  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
127  | 
|
128  | 
__docformat__ = "restructuredtext en"  | 
|
129  | 
||
130  | 
__all__ = (  | 
|
131  | 
'__version__',  | 
|
132  | 
'DEFAULT_INDENT_TYPE',  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
133  | 
'DEFAULT_INTERPOLATION',  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
134  | 
'ConfigObjError',  | 
135  | 
'NestingError',  | 
|
136  | 
'ParseError',  | 
|
137  | 
'DuplicateError',  | 
|
138  | 
'ConfigspecError',  | 
|
139  | 
'ConfigObj',  | 
|
140  | 
'SimpleVal',  | 
|
141  | 
'InterpolationError',  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
142  | 
'InterpolationLoopError',  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
143  | 
'MissingInterpolationOption',  | 
144  | 
'RepeatSectionError',  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
145  | 
'ReloadError',  | 
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
146  | 
'UnreprError',  | 
147  | 
'UnknownType',  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
148  | 
'__docformat__',  | 
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
149  | 
'flatten_errors',  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
150  | 
)
 | 
151  | 
||
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
152  | 
DEFAULT_INTERPOLATION = 'configparser'  | 
153  | 
DEFAULT_INDENT_TYPE = ' '  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
154  | 
MAX_INTERPOL_DEPTH = 10  | 
155  | 
||
156  | 
OPTION_DEFAULTS = {  | 
|
157  | 
'interpolation': True,  | 
|
158  | 
'raise_errors': False,  | 
|
159  | 
'list_values': True,  | 
|
160  | 
'create_empty': False,  | 
|
161  | 
'file_error': False,  | 
|
162  | 
'configspec': None,  | 
|
163  | 
'stringify': True,  | 
|
164  | 
    # option may be set to one of ('', ' ', '\t')
 | 
|
165  | 
'indent_type': None,  | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
166  | 
'encoding': None,  | 
167  | 
'default_encoding': None,  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
168  | 
'unrepr': False,  | 
169  | 
'write_empty_values': False,  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
170  | 
}
 | 
171  | 
||
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
172  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
173  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
174  | 
def getObj(s):  | 
175  | 
s = "a=" + s  | 
|
176  | 
if compiler is None:  | 
|
177  | 
raise ImportError('compiler module not available')  | 
|
178  | 
p = compiler.parse(s)  | 
|
179  | 
return p.getChildren()[1].getChildren()[0].getChildren()[1]  | 
|
180  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
181  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
182  | 
class UnknownType(Exception):  | 
183  | 
    pass
 | 
|
184  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
185  | 
|
186  | 
class Builder(object):  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
187  | 
|
188  | 
def build(self, o):  | 
|
189  | 
m = getattr(self, 'build_' + o.__class__.__name__, None)  | 
|
190  | 
if m is None:  | 
|
191  | 
raise UnknownType(o.__class__.__name__)  | 
|
192  | 
return m(o)  | 
|
193  | 
||
194  | 
def build_List(self, o):  | 
|
195  | 
return map(self.build, o.getChildren())  | 
|
196  | 
||
197  | 
def build_Const(self, o):  | 
|
198  | 
return o.value  | 
|
199  | 
||
200  | 
def build_Dict(self, o):  | 
|
201  | 
d = {}  | 
|
202  | 
i = iter(map(self.build, o.getChildren()))  | 
|
203  | 
for el in i:  | 
|
204  | 
d[el] = i.next()  | 
|
205  | 
return d  | 
|
206  | 
||
207  | 
def build_Tuple(self, o):  | 
|
208  | 
return tuple(self.build_List(o))  | 
|
209  | 
||
210  | 
def build_Name(self, o):  | 
|
211  | 
if o.name == 'None':  | 
|
212  | 
return None  | 
|
213  | 
if o.name == 'True':  | 
|
214  | 
return True  | 
|
215  | 
if o.name == 'False':  | 
|
216  | 
return False  | 
|
217  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
218  | 
        # An undefined Name
 | 
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
219  | 
raise UnknownType('Undefined Name')  | 
220  | 
||
221  | 
def build_Add(self, o):  | 
|
222  | 
real, imag = map(self.build_Const, o.getChildren())  | 
|
223  | 
try:  | 
|
224  | 
real = float(real)  | 
|
225  | 
except TypeError:  | 
|
226  | 
raise UnknownType('Add')  | 
|
227  | 
if not isinstance(imag, complex) or imag.real != 0.0:  | 
|
228  | 
raise UnknownType('Add')  | 
|
229  | 
return real+imag  | 
|
230  | 
||
231  | 
def build_Getattr(self, o):  | 
|
232  | 
parent = self.build(o.expr)  | 
|
233  | 
return getattr(parent, o.attrname)  | 
|
234  | 
||
235  | 
def build_UnarySub(self, o):  | 
|
236  | 
return -self.build_Const(o.getChildren()[0])  | 
|
237  | 
||
238  | 
def build_UnaryAdd(self, o):  | 
|
239  | 
return self.build_Const(o.getChildren()[0])  | 
|
240  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
241  | 
|
242  | 
_builder = Builder()  | 
|
243  | 
||
244  | 
||
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
245  | 
def unrepr(s):  | 
246  | 
if not s:  | 
|
247  | 
return s  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
248  | 
return _builder.build(getObj(s))  | 
249  | 
||
250  | 
||
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
251  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
252  | 
class ConfigObjError(SyntaxError):  | 
253  | 
"""  | 
|
254  | 
    This is the base class for all errors that ConfigObj raises.
 | 
|
255  | 
    It is a subclass of SyntaxError.
 | 
|
256  | 
    """
 | 
|
| 
2929.3.5
by Vincent Ladeuil
 New files, same warnings, same fixes.  | 
257  | 
def __init__(self, msg='', line_number=None, line=''):  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
258  | 
self.line = line  | 
259  | 
self.line_number = line_number  | 
|
| 
2929.3.5
by Vincent Ladeuil
 New files, same warnings, same fixes.  | 
260  | 
self.msg = msg  | 
261  | 
SyntaxError.__init__(self, msg)  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
262  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
263  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
264  | 
class NestingError(ConfigObjError):  | 
265  | 
"""  | 
|
266  | 
    This error indicates a level of nesting that doesn't match.
 | 
|
267  | 
    """
 | 
|
268  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
269  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
270  | 
class ParseError(ConfigObjError):  | 
271  | 
"""  | 
|
272  | 
    This error indicates that a line is badly written.
 | 
|
273  | 
    It is neither a valid ``key = value`` line,
 | 
|
274  | 
    nor a valid section marker line.
 | 
|
275  | 
    """
 | 
|
276  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
277  | 
|
278  | 
class ReloadError(IOError):  | 
|
279  | 
"""  | 
|
280  | 
    A 'reload' operation failed.
 | 
|
281  | 
    This exception is a subclass of ``IOError``.
 | 
|
282  | 
    """
 | 
|
283  | 
def __init__(self):  | 
|
284  | 
IOError.__init__(self, 'reload failed, filename is not set.')  | 
|
285  | 
||
286  | 
||
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
287  | 
class DuplicateError(ConfigObjError):  | 
288  | 
"""  | 
|
289  | 
    The keyword or section specified already exists.
 | 
|
290  | 
    """
 | 
|
291  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
292  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
293  | 
class ConfigspecError(ConfigObjError):  | 
294  | 
"""  | 
|
295  | 
    An error occured whilst parsing a configspec.
 | 
|
296  | 
    """
 | 
|
297  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
298  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
299  | 
class InterpolationError(ConfigObjError):  | 
300  | 
"""Base class for the two interpolation errors."""  | 
|
301  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
302  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
303  | 
class InterpolationLoopError(InterpolationError):  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
304  | 
"""Maximum interpolation depth exceeded in string interpolation."""  | 
305  | 
||
306  | 
def __init__(self, option):  | 
|
307  | 
InterpolationError.__init__(  | 
|
308  | 
self,  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
309  | 
'interpolation loop detected in value "%s".' % option)  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
310  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
311  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
312  | 
class RepeatSectionError(ConfigObjError):  | 
313  | 
"""  | 
|
314  | 
    This error indicates additional sections in a section with a
 | 
|
315  | 
    ``__many__`` (repeated) section.
 | 
|
316  | 
    """
 | 
|
317  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
318  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
319  | 
class MissingInterpolationOption(InterpolationError):  | 
320  | 
"""A value specified for interpolation was missing."""  | 
|
321  | 
||
322  | 
def __init__(self, option):  | 
|
323  | 
InterpolationError.__init__(  | 
|
324  | 
self,  | 
|
325  | 
'missing option "%s" in interpolation.' % option)  | 
|
326  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
327  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
328  | 
class UnreprError(ConfigObjError):  | 
329  | 
"""An error parsing in unrepr mode."""  | 
|
330  | 
||
331  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
332  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
333  | 
class InterpolationEngine(object):  | 
334  | 
"""  | 
|
335  | 
    A helper class to help perform string interpolation.
 | 
|
336  | 
||
337  | 
    This class is an abstract base class; its descendants perform
 | 
|
338  | 
    the actual work.
 | 
|
339  | 
    """
 | 
|
340  | 
||
341  | 
    # compiled regexp to use in self.interpolate()
 | 
|
342  | 
_KEYCRE = re.compile(r"%\(([^)]*)\)s")  | 
|
343  | 
||
344  | 
def __init__(self, section):  | 
|
345  | 
        # the Section instance that "owns" this engine
 | 
|
346  | 
self.section = section  | 
|
347  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
348  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
349  | 
def interpolate(self, key, value):  | 
350  | 
def recursive_interpolate(key, value, section, backtrail):  | 
|
351  | 
"""The function that does the actual work.  | 
|
352  | 
||
353  | 
            ``value``: the string we're trying to interpolate.
 | 
|
354  | 
            ``section``: the section in which that string was found
 | 
|
355  | 
            ``backtrail``: a dict to keep track of where we've been,
 | 
|
356  | 
            to detect and prevent infinite recursion loops
 | 
|
357  | 
||
358  | 
            This is similar to a depth-first-search algorithm.
 | 
|
359  | 
            """
 | 
|
360  | 
            # Have we been here already?
 | 
|
361  | 
if backtrail.has_key((key, section.name)):  | 
|
362  | 
                # Yes - infinite loop detected
 | 
|
363  | 
raise InterpolationLoopError(key)  | 
|
364  | 
            # Place a marker on our backtrail so we won't come back here again
 | 
|
365  | 
backtrail[(key, section.name)] = 1  | 
|
366  | 
||
367  | 
            # Now start the actual work
 | 
|
368  | 
match = self._KEYCRE.search(value)  | 
|
369  | 
while match:  | 
|
370  | 
                # The actual parsing of the match is implementation-dependent,
 | 
|
371  | 
                # so delegate to our helper function
 | 
|
372  | 
k, v, s = self._parse_match(match)  | 
|
373  | 
if k is None:  | 
|
374  | 
                    # That's the signal that no further interpolation is needed
 | 
|
375  | 
replacement = v  | 
|
376  | 
else:  | 
|
377  | 
                    # Further interpolation may be needed to obtain final value
 | 
|
378  | 
replacement = recursive_interpolate(k, v, s, backtrail)  | 
|
379  | 
                # Replace the matched string with its final value
 | 
|
380  | 
start, end = match.span()  | 
|
381  | 
value = ''.join((value[:start], replacement, value[end:]))  | 
|
382  | 
new_search_start = start + len(replacement)  | 
|
383  | 
                # Pick up the next interpolation key, if any, for next time
 | 
|
384  | 
                # through the while loop
 | 
|
385  | 
match = self._KEYCRE.search(value, new_search_start)  | 
|
386  | 
||
387  | 
            # Now safe to come back here again; remove marker from backtrail
 | 
|
388  | 
del backtrail[(key, section.name)]  | 
|
389  | 
||
390  | 
return value  | 
|
391  | 
||
392  | 
        # Back in interpolate(), all we have to do is kick off the recursive
 | 
|
393  | 
        # function with appropriate starting values
 | 
|
394  | 
value = recursive_interpolate(key, value, self.section, {})  | 
|
395  | 
return value  | 
|
396  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
397  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
398  | 
def _fetch(self, key):  | 
399  | 
"""Helper function to fetch values from owning section.  | 
|
400  | 
||
401  | 
        Returns a 2-tuple: the value, and the section where it was found.
 | 
|
402  | 
        """
 | 
|
403  | 
        # switch off interpolation before we try and fetch anything !
 | 
|
404  | 
save_interp = self.section.main.interpolation  | 
|
405  | 
self.section.main.interpolation = False  | 
|
406  | 
||
407  | 
        # Start at section that "owns" this InterpolationEngine
 | 
|
408  | 
current_section = self.section  | 
|
409  | 
while True:  | 
|
410  | 
            # try the current section first
 | 
|
411  | 
val = current_section.get(key)  | 
|
412  | 
if val is not None:  | 
|
413  | 
                break
 | 
|
414  | 
            # try "DEFAULT" next
 | 
|
415  | 
val = current_section.get('DEFAULT', {}).get(key)  | 
|
416  | 
if val is not None:  | 
|
417  | 
                break
 | 
|
418  | 
            # move up to parent and try again
 | 
|
419  | 
            # top-level's parent is itself
 | 
|
420  | 
if current_section.parent is current_section:  | 
|
421  | 
                # reached top level, time to give up
 | 
|
422  | 
                break
 | 
|
423  | 
current_section = current_section.parent  | 
|
424  | 
||
425  | 
        # restore interpolation to previous value before returning
 | 
|
426  | 
self.section.main.interpolation = save_interp  | 
|
427  | 
if val is None:  | 
|
428  | 
raise MissingInterpolationOption(key)  | 
|
429  | 
return val, current_section  | 
|
430  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
431  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
432  | 
def _parse_match(self, match):  | 
433  | 
"""Implementation-dependent helper function.  | 
|
434  | 
||
435  | 
        Will be passed a match object corresponding to the interpolation
 | 
|
436  | 
        key we just found (e.g., "%(foo)s" or "$foo"). Should look up that
 | 
|
437  | 
        key in the appropriate config file section (using the ``_fetch()``
 | 
|
438  | 
        helper function) and return a 3-tuple: (key, value, section)
 | 
|
439  | 
||
440  | 
        ``key`` is the name of the key we're looking for
 | 
|
441  | 
        ``value`` is the value found for that key
 | 
|
442  | 
        ``section`` is a reference to the section where it was found
 | 
|
443  | 
||
444  | 
        ``key`` and ``section`` should be None if no further
 | 
|
445  | 
        interpolation should be performed on the resulting value
 | 
|
446  | 
        (e.g., if we interpolated "$$" and returned "$").
 | 
|
447  | 
        """
 | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
448  | 
raise NotImplementedError()  | 
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
449  | 
|
450  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
451  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
452  | 
class ConfigParserInterpolation(InterpolationEngine):  | 
453  | 
"""Behaves like ConfigParser."""  | 
|
454  | 
_KEYCRE = re.compile(r"%\(([^)]*)\)s")  | 
|
455  | 
||
456  | 
def _parse_match(self, match):  | 
|
457  | 
key = match.group(1)  | 
|
458  | 
value, section = self._fetch(key)  | 
|
459  | 
return key, value, section  | 
|
460  | 
||
461  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
462  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
463  | 
class TemplateInterpolation(InterpolationEngine):  | 
464  | 
"""Behaves like string.Template."""  | 
|
465  | 
_delimiter = '$'  | 
|
466  | 
_KEYCRE = re.compile(r"""  | 
|
467  | 
        \$(?:
 | 
|
468  | 
          (?P<escaped>\$)              |   # Two $ signs
 | 
|
469  | 
          (?P<named>[_a-z][_a-z0-9]*)  |   # $name format
 | 
|
470  | 
{(?P<braced>[^}]*)} # ${name} format  | 
|
471  | 
        )
 | 
|
472  | 
""", re.IGNORECASE | re.VERBOSE)  | 
|
473  | 
||
474  | 
def _parse_match(self, match):  | 
|
475  | 
        # Valid name (in or out of braces): fetch value from section
 | 
|
476  | 
key = match.group('named') or match.group('braced')  | 
|
477  | 
if key is not None:  | 
|
478  | 
value, section = self._fetch(key)  | 
|
479  | 
return key, value, section  | 
|
480  | 
        # Escaped delimiter (e.g., $$): return single delimiter
 | 
|
481  | 
if match.group('escaped') is not None:  | 
|
482  | 
            # Return None for key and section to indicate it's time to stop
 | 
|
483  | 
return None, self._delimiter, None  | 
|
484  | 
        # Anything else: ignore completely, just return it unchanged
 | 
|
485  | 
return None, match.group(), None  | 
|
486  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
487  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
488  | 
interpolation_engines = {  | 
489  | 
'configparser': ConfigParserInterpolation,  | 
|
490  | 
'template': TemplateInterpolation,  | 
|
491  | 
}
 | 
|
492  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
493  | 
|
494  | 
||
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
495  | 
class Section(dict):  | 
496  | 
"""  | 
|
497  | 
    A dictionary-like object that represents a section in a config file.
 | 
|
498  | 
    
 | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
499  | 
    It does string interpolation if the 'interpolation' attribute
 | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
500  | 
    of the 'main' object is set to True.
 | 
501  | 
    
 | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
502  | 
    Interpolation is tried first from this object, then from the 'DEFAULT'
 | 
503  | 
    section of this object, next from the parent and its 'DEFAULT' section,
 | 
|
504  | 
    and so on until the main object is reached.
 | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
505  | 
    
 | 
506  | 
    A Section will behave like an ordered dictionary - following the
 | 
|
507  | 
    order of the ``scalars`` and ``sections`` attributes.
 | 
|
508  | 
    You can use this to change the order of members.
 | 
|
509  | 
    
 | 
|
510  | 
    Iteration follows the order: scalars, then sections.
 | 
|
511  | 
    """
 | 
|
512  | 
||
513  | 
def __init__(self, parent, depth, main, indict=None, name=None):  | 
|
514  | 
"""  | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
515  | 
        * parent is the section above
 | 
516  | 
        * depth is the depth level of this section
 | 
|
517  | 
        * main is the main ConfigObj
 | 
|
518  | 
        * indict is a dictionary to initialise the section with
 | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
519  | 
        """
 | 
520  | 
if indict is None:  | 
|
521  | 
indict = {}  | 
|
522  | 
dict.__init__(self)  | 
|
523  | 
        # used for nesting level *and* interpolation
 | 
|
524  | 
self.parent = parent  | 
|
525  | 
        # used for the interpolation attribute
 | 
|
526  | 
self.main = main  | 
|
527  | 
        # level of nesting depth of this Section
 | 
|
528  | 
self.depth = depth  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
529  | 
        # purely for information
 | 
530  | 
self.name = name  | 
|
531  | 
        #
 | 
|
532  | 
self._initialise()  | 
|
533  | 
        # we do this explicitly so that __setitem__ is used properly
 | 
|
534  | 
        # (rather than just passing to ``dict.__init__``)
 | 
|
535  | 
for entry, value in indict.iteritems():  | 
|
536  | 
self[entry] = value  | 
|
537  | 
||
538  | 
||
539  | 
def _initialise(self):  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
540  | 
        # the sequence of scalar values in this Section
 | 
541  | 
self.scalars = []  | 
|
542  | 
        # the sequence of sections in this Section
 | 
|
543  | 
self.sections = []  | 
|
544  | 
        # for comments :-)
 | 
|
545  | 
self.comments = {}  | 
|
546  | 
self.inline_comments = {}  | 
|
547  | 
        # for the configspec
 | 
|
548  | 
self.configspec = {}  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
549  | 
self._order = []  | 
550  | 
self._configspec_comments = {}  | 
|
551  | 
self._configspec_inline_comments = {}  | 
|
552  | 
self._cs_section_comments = {}  | 
|
553  | 
self._cs_section_inline_comments = {}  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
554  | 
        # for defaults
 | 
555  | 
self.defaults = []  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
556  | 
self.default_values = {}  | 
557  | 
||
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
558  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
559  | 
def _interpolate(self, key, value):  | 
560  | 
try:  | 
|
561  | 
            # do we already have an interpolation engine?
 | 
|
562  | 
engine = self._interpolation_engine  | 
|
563  | 
except AttributeError:  | 
|
564  | 
            # not yet: first time running _interpolate(), so pick the engine
 | 
|
565  | 
name = self.main.interpolation  | 
|
566  | 
if name == True: # note that "if name:" would be incorrect here  | 
|
567  | 
                # backwards-compatibility: interpolation=True means use default
 | 
|
568  | 
name = DEFAULT_INTERPOLATION  | 
|
569  | 
name = name.lower() # so that "Template", "template", etc. all work  | 
|
570  | 
class_ = interpolation_engines.get(name, None)  | 
|
571  | 
if class_ is None:  | 
|
572  | 
                # invalid value for self.main.interpolation
 | 
|
573  | 
self.main.interpolation = False  | 
|
574  | 
return value  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
575  | 
else:  | 
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
576  | 
                # save reference to engine so we don't have to do this again
 | 
577  | 
engine = self._interpolation_engine = class_(self)  | 
|
578  | 
        # let the engine do the actual work
 | 
|
579  | 
return engine.interpolate(key, value)  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
580  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
581  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
582  | 
def __getitem__(self, key):  | 
583  | 
"""Fetch the item and do string interpolation."""  | 
|
584  | 
val = dict.__getitem__(self, key)  | 
|
585  | 
if self.main.interpolation and isinstance(val, StringTypes):  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
586  | 
return self._interpolate(key, val)  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
587  | 
return val  | 
588  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
589  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
590  | 
def __setitem__(self, key, value, unrepr=False):  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
591  | 
"""  | 
592  | 
        Correctly set a value.
 | 
|
593  | 
        
 | 
|
594  | 
        Making dictionary values Section instances.
 | 
|
595  | 
        (We have to special case 'Section' instances - which are also dicts)
 | 
|
596  | 
        
 | 
|
597  | 
        Keys must be strings.
 | 
|
598  | 
        Values need only be strings (or lists of strings) if
 | 
|
599  | 
        ``main.stringify`` is set.
 | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
600  | 
        
 | 
601  | 
        `unrepr`` must be set when setting a value to a dictionary, without
 | 
|
602  | 
        creating a new sub-section.
 | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
603  | 
        """
 | 
604  | 
if not isinstance(key, StringTypes):  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
605  | 
raise ValueError('The key "%s" is not a string.' % key)  | 
606  | 
||
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
607  | 
        # add the comment
 | 
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
608  | 
if not self.comments.has_key(key):  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
609  | 
self.comments[key] = []  | 
610  | 
self.inline_comments[key] = ''  | 
|
611  | 
        # remove the entry from defaults
 | 
|
612  | 
if key in self.defaults:  | 
|
613  | 
self.defaults.remove(key)  | 
|
614  | 
        #
 | 
|
615  | 
if isinstance(value, Section):  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
616  | 
if not self.has_key(key):  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
617  | 
self.sections.append(key)  | 
618  | 
dict.__setitem__(self, key, value)  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
619  | 
elif isinstance(value, dict) and not unrepr:  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
620  | 
            # First create the new depth level,
 | 
621  | 
            # then create the section
 | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
622  | 
if not self.has_key(key):  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
623  | 
self.sections.append(key)  | 
624  | 
new_depth = self.depth + 1  | 
|
625  | 
dict.__setitem__(  | 
|
626  | 
self,  | 
|
627  | 
key,  | 
|
628  | 
Section(  | 
|
629  | 
self,  | 
|
630  | 
new_depth,  | 
|
631  | 
self.main,  | 
|
632  | 
indict=value,  | 
|
633  | 
name=key))  | 
|
634  | 
else:  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
635  | 
if not self.has_key(key):  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
636  | 
self.scalars.append(key)  | 
637  | 
if not self.main.stringify:  | 
|
638  | 
if isinstance(value, StringTypes):  | 
|
639  | 
                    pass
 | 
|
640  | 
elif isinstance(value, (list, tuple)):  | 
|
641  | 
for entry in value:  | 
|
642  | 
if not isinstance(entry, StringTypes):  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
643  | 
raise TypeError('Value is not a string "%s".' % entry)  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
644  | 
else:  | 
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
645  | 
raise TypeError('Value is not a string "%s".' % value)  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
646  | 
dict.__setitem__(self, key, value)  | 
647  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
648  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
649  | 
def __delitem__(self, key):  | 
650  | 
"""Remove items from the sequence when deleting."""  | 
|
651  | 
dict. __delitem__(self, key)  | 
|
652  | 
if key in self.scalars:  | 
|
653  | 
self.scalars.remove(key)  | 
|
654  | 
else:  | 
|
655  | 
self.sections.remove(key)  | 
|
656  | 
del self.comments[key]  | 
|
657  | 
del self.inline_comments[key]  | 
|
658  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
659  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
660  | 
def get(self, key, default=None):  | 
661  | 
"""A version of ``get`` that doesn't bypass string interpolation."""  | 
|
662  | 
try:  | 
|
663  | 
return self[key]  | 
|
664  | 
except KeyError:  | 
|
665  | 
return default  | 
|
666  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
667  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
668  | 
def update(self, indict):  | 
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
669  | 
"""  | 
670  | 
        A version of update that uses our ``__setitem__``.
 | 
|
671  | 
        """
 | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
672  | 
for entry in indict:  | 
673  | 
self[entry] = indict[entry]  | 
|
674  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
675  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
676  | 
def pop(self, key, *args):  | 
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
677  | 
"""  | 
678  | 
        'D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
 | 
|
679  | 
        If key is not found, d is returned if given, otherwise KeyError is raised'
 | 
|
680  | 
        """
 | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
681  | 
val = dict.pop(self, key, *args)  | 
682  | 
if key in self.scalars:  | 
|
683  | 
del self.comments[key]  | 
|
684  | 
del self.inline_comments[key]  | 
|
685  | 
self.scalars.remove(key)  | 
|
686  | 
elif key in self.sections:  | 
|
687  | 
del self.comments[key]  | 
|
688  | 
del self.inline_comments[key]  | 
|
689  | 
self.sections.remove(key)  | 
|
690  | 
if self.main.interpolation and isinstance(val, StringTypes):  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
691  | 
return self._interpolate(key, val)  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
692  | 
return val  | 
693  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
694  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
695  | 
def popitem(self):  | 
696  | 
"""Pops the first (key,val)"""  | 
|
697  | 
sequence = (self.scalars + self.sections)  | 
|
698  | 
if not sequence:  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
699  | 
raise KeyError(": 'popitem(): dictionary is empty'")  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
700  | 
key = sequence[0]  | 
701  | 
val = self[key]  | 
|
702  | 
del self[key]  | 
|
703  | 
return key, val  | 
|
704  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
705  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
706  | 
def clear(self):  | 
707  | 
"""  | 
|
708  | 
        A version of clear that also affects scalars/sections
 | 
|
709  | 
        Also clears comments and configspec.
 | 
|
710  | 
        
 | 
|
711  | 
        Leaves other attributes alone :
 | 
|
712  | 
            depth/main/parent are not affected
 | 
|
713  | 
        """
 | 
|
714  | 
dict.clear(self)  | 
|
715  | 
self.scalars = []  | 
|
716  | 
self.sections = []  | 
|
717  | 
self.comments = {}  | 
|
718  | 
self.inline_comments = {}  | 
|
719  | 
self.configspec = {}  | 
|
720  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
721  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
722  | 
def setdefault(self, key, default=None):  | 
723  | 
"""A version of setdefault that sets sequence if appropriate."""  | 
|
724  | 
try:  | 
|
725  | 
return self[key]  | 
|
726  | 
except KeyError:  | 
|
727  | 
self[key] = default  | 
|
728  | 
return self[key]  | 
|
729  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
730  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
731  | 
def items(self):  | 
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
732  | 
"""D.items() -> list of D's (key, value) pairs, as 2-tuples"""  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
733  | 
return zip((self.scalars + self.sections), self.values())  | 
734  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
735  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
736  | 
def keys(self):  | 
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
737  | 
"""D.keys() -> list of D's keys"""  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
738  | 
return (self.scalars + self.sections)  | 
739  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
740  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
741  | 
def values(self):  | 
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
742  | 
"""D.values() -> list of D's values"""  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
743  | 
return [self[key] for key in (self.scalars + self.sections)]  | 
744  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
745  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
746  | 
def iteritems(self):  | 
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
747  | 
"""D.iteritems() -> an iterator over the (key, value) items of D"""  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
748  | 
return iter(self.items())  | 
749  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
750  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
751  | 
def iterkeys(self):  | 
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
752  | 
"""D.iterkeys() -> an iterator over the keys of D"""  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
753  | 
return iter((self.scalars + self.sections))  | 
754  | 
||
755  | 
__iter__ = iterkeys  | 
|
756  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
757  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
758  | 
def itervalues(self):  | 
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
759  | 
"""D.itervalues() -> an iterator over the values of D"""  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
760  | 
return iter(self.values())  | 
761  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
762  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
763  | 
def __repr__(self):  | 
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
764  | 
"""x.__repr__() <==> repr(x)"""  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
765  | 
return '{%s}' % ', '.join([('%s: %s' % (repr(key), repr(self[key])))  | 
766  | 
for key in (self.scalars + self.sections)])  | 
|
767  | 
||
768  | 
__str__ = __repr__  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
769  | 
__str__.__doc__ = "x.__str__() <==> str(x)"  | 
770  | 
||
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
771  | 
|
772  | 
    # Extra methods - not in a normal dictionary
 | 
|
773  | 
||
774  | 
def dict(self):  | 
|
775  | 
"""  | 
|
776  | 
        Return a deepcopy of self as a dictionary.
 | 
|
777  | 
        
 | 
|
778  | 
        All members that are ``Section`` instances are recursively turned to
 | 
|
779  | 
        ordinary dictionaries - by calling their ``dict`` method.
 | 
|
780  | 
        
 | 
|
781  | 
        >>> n = a.dict()
 | 
|
782  | 
        >>> n == a
 | 
|
783  | 
        1
 | 
|
784  | 
        >>> n is a
 | 
|
785  | 
        0
 | 
|
786  | 
        """
 | 
|
787  | 
newdict = {}  | 
|
788  | 
for entry in self:  | 
|
789  | 
this_entry = self[entry]  | 
|
790  | 
if isinstance(this_entry, Section):  | 
|
791  | 
this_entry = this_entry.dict()  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
792  | 
elif isinstance(this_entry, list):  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
793  | 
                # create a copy rather than a reference
 | 
794  | 
this_entry = list(this_entry)  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
795  | 
elif isinstance(this_entry, tuple):  | 
796  | 
                # create a copy rather than a reference
 | 
|
797  | 
this_entry = tuple(this_entry)  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
798  | 
newdict[entry] = this_entry  | 
799  | 
return newdict  | 
|
800  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
801  | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
802  | 
def merge(self, indict):  | 
803  | 
"""  | 
|
804  | 
        A recursive update - useful for merging config files.
 | 
|
805  | 
        
 | 
|
806  | 
        >>> a = '''[section1]
 | 
|
807  | 
        ...     option1 = True
 | 
|
808  | 
        ...     [[subsection]]
 | 
|
809  | 
        ...     more_options = False
 | 
|
810  | 
        ...     # end of file'''.splitlines()
 | 
|
811  | 
        >>> b = '''# File is user.ini
 | 
|
812  | 
        ...     [section1]
 | 
|
813  | 
        ...     option1 = False
 | 
|
814  | 
        ...     # end of file'''.splitlines()
 | 
|
815  | 
        >>> c1 = ConfigObj(b)
 | 
|
816  | 
        >>> c2 = ConfigObj(a)
 | 
|
817  | 
        >>> c2.merge(c1)
 | 
|
818  | 
        >>> c2
 | 
|
819  | 
        {'section1': {'option1': 'False', 'subsection': {'more_options': 'False'}}}
 | 
|
820  | 
        """
 | 
|
821  | 
for key, val in indict.items():  | 
|
822  | 
if (key in self and isinstance(self[key], dict) and  | 
|
823  | 
isinstance(val, dict)):  | 
|
824  | 
self[key].merge(val)  | 
|
825  | 
else:  | 
|
826  | 
self[key] = val  | 
|
827  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
828  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
829  | 
def rename(self, oldkey, newkey):  | 
830  | 
"""  | 
|
831  | 
        Change a keyname to another, without changing position in sequence.
 | 
|
832  | 
        
 | 
|
833  | 
        Implemented so that transformations can be made on keys,
 | 
|
834  | 
        as well as on values. (used by encode and decode)
 | 
|
835  | 
        
 | 
|
836  | 
        Also renames comments.
 | 
|
837  | 
        """
 | 
|
838  | 
if oldkey in self.scalars:  | 
|
839  | 
the_list = self.scalars  | 
|
840  | 
elif oldkey in self.sections:  | 
|
841  | 
the_list = self.sections  | 
|
842  | 
else:  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
843  | 
raise KeyError('Key "%s" not found.' % oldkey)  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
844  | 
pos = the_list.index(oldkey)  | 
845  | 
        #
 | 
|
846  | 
val = self[oldkey]  | 
|
847  | 
dict.__delitem__(self, oldkey)  | 
|
848  | 
dict.__setitem__(self, newkey, val)  | 
|
849  | 
the_list.remove(oldkey)  | 
|
850  | 
the_list.insert(pos, newkey)  | 
|
851  | 
comm = self.comments[oldkey]  | 
|
852  | 
inline_comment = self.inline_comments[oldkey]  | 
|
853  | 
del self.comments[oldkey]  | 
|
854  | 
del self.inline_comments[oldkey]  | 
|
855  | 
self.comments[newkey] = comm  | 
|
856  | 
self.inline_comments[newkey] = inline_comment  | 
|
857  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
858  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
859  | 
def walk(self, function, raise_errors=True,  | 
860  | 
call_on_sections=False, **keywargs):  | 
|
861  | 
"""  | 
|
862  | 
        Walk every member and call a function on the keyword and value.
 | 
|
863  | 
        
 | 
|
864  | 
        Return a dictionary of the return values
 | 
|
865  | 
        
 | 
|
866  | 
        If the function raises an exception, raise the errror
 | 
|
867  | 
        unless ``raise_errors=False``, in which case set the return value to
 | 
|
868  | 
        ``False``.
 | 
|
869  | 
        
 | 
|
870  | 
        Any unrecognised keyword arguments you pass to walk, will be pased on
 | 
|
871  | 
        to the function you pass in.
 | 
|
872  | 
        
 | 
|
873  | 
        Note: if ``call_on_sections`` is ``True`` then - on encountering a
 | 
|
874  | 
        subsection, *first* the function is called for the *whole* subsection,
 | 
|
875  | 
        and then recurses into it's members. This means your function must be
 | 
|
876  | 
        able to handle strings, dictionaries and lists. This allows you
 | 
|
877  | 
        to change the key of subsections as well as for ordinary members. The
 | 
|
878  | 
        return value when called on the whole subsection has to be discarded.
 | 
|
879  | 
        
 | 
|
880  | 
        See  the encode and decode methods for examples, including functions.
 | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
881  | 
        
 | 
882  | 
        .. caution::
 | 
|
883  | 
        
 | 
|
884  | 
            You can use ``walk`` to transform the names of members of a section
 | 
|
885  | 
            but you mustn't add or delete members.
 | 
|
886  | 
        
 | 
|
887  | 
        >>> config = '''[XXXXsection]
 | 
|
888  | 
        ... XXXXkey = XXXXvalue'''.splitlines()
 | 
|
889  | 
        >>> cfg = ConfigObj(config)
 | 
|
890  | 
        >>> cfg
 | 
|
891  | 
        {'XXXXsection': {'XXXXkey': 'XXXXvalue'}}
 | 
|
892  | 
        >>> def transform(section, key):
 | 
|
893  | 
        ...     val = section[key]
 | 
|
894  | 
        ...     newkey = key.replace('XXXX', 'CLIENT1')
 | 
|
895  | 
        ...     section.rename(key, newkey)
 | 
|
896  | 
        ...     if isinstance(val, (tuple, list, dict)):
 | 
|
897  | 
        ...         pass
 | 
|
898  | 
        ...     else:
 | 
|
899  | 
        ...         val = val.replace('XXXX', 'CLIENT1')
 | 
|
900  | 
        ...         section[newkey] = val
 | 
|
901  | 
        >>> cfg.walk(transform, call_on_sections=True)
 | 
|
902  | 
        {'CLIENT1section': {'CLIENT1key': None}}
 | 
|
903  | 
        >>> cfg
 | 
|
904  | 
        {'CLIENT1section': {'CLIENT1key': 'CLIENT1value'}}
 | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
905  | 
        """
 | 
906  | 
out = {}  | 
|
907  | 
        # scalars first
 | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
908  | 
for i in range(len(self.scalars)):  | 
909  | 
entry = self.scalars[i]  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
910  | 
try:  | 
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
911  | 
val = function(self, entry, **keywargs)  | 
912  | 
                # bound again in case name has changed
 | 
|
913  | 
entry = self.scalars[i]  | 
|
914  | 
out[entry] = val  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
915  | 
except Exception:  | 
916  | 
if raise_errors:  | 
|
917  | 
                    raise
 | 
|
918  | 
else:  | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
919  | 
entry = self.scalars[i]  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
920  | 
out[entry] = False  | 
921  | 
        # then sections
 | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
922  | 
for i in range(len(self.sections)):  | 
923  | 
entry = self.sections[i]  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
924  | 
if call_on_sections:  | 
925  | 
try:  | 
|
926  | 
function(self, entry, **keywargs)  | 
|
927  | 
except Exception:  | 
|
928  | 
if raise_errors:  | 
|
929  | 
                        raise
 | 
|
930  | 
else:  | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
931  | 
entry = self.sections[i]  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
932  | 
out[entry] = False  | 
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
933  | 
                # bound again in case name has changed
 | 
934  | 
entry = self.sections[i]  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
935  | 
            # previous result is discarded
 | 
936  | 
out[entry] = self[entry].walk(  | 
|
937  | 
function,  | 
|
938  | 
raise_errors=raise_errors,  | 
|
939  | 
call_on_sections=call_on_sections,  | 
|
940  | 
**keywargs)  | 
|
941  | 
return out  | 
|
942  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
943  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
944  | 
def decode(self, encoding):  | 
945  | 
"""  | 
|
946  | 
        Decode all strings and values to unicode, using the specified encoding.
 | 
|
947  | 
        
 | 
|
948  | 
        Works with subsections and list values.
 | 
|
949  | 
        
 | 
|
950  | 
        Uses the ``walk`` method.
 | 
|
951  | 
        
 | 
|
952  | 
        Testing ``encode`` and ``decode``.
 | 
|
953  | 
        >>> m = ConfigObj(a)
 | 
|
954  | 
        >>> m.decode('ascii')
 | 
|
955  | 
        >>> def testuni(val):
 | 
|
956  | 
        ...     for entry in val:
 | 
|
957  | 
        ...         if not isinstance(entry, unicode):
 | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
958  | 
        ...             print >> sys.stderr, type(entry)
 | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
959  | 
        ...             raise AssertionError, 'decode failed.'
 | 
960  | 
        ...         if isinstance(val[entry], dict):
 | 
|
961  | 
        ...             testuni(val[entry])
 | 
|
962  | 
        ...         elif not isinstance(val[entry], unicode):
 | 
|
963  | 
        ...             raise AssertionError, 'decode failed.'
 | 
|
964  | 
        >>> testuni(m)
 | 
|
965  | 
        >>> m.encode('ascii')
 | 
|
966  | 
        >>> a == m
 | 
|
967  | 
        1
 | 
|
968  | 
        """
 | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
969  | 
warn('use of ``decode`` is deprecated.', DeprecationWarning)  | 
970  | 
def decode(section, key, encoding=encoding, warn=True):  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
971  | 
""" """  | 
972  | 
val = section[key]  | 
|
973  | 
if isinstance(val, (list, tuple)):  | 
|
974  | 
newval = []  | 
|
975  | 
for entry in val:  | 
|
976  | 
newval.append(entry.decode(encoding))  | 
|
977  | 
elif isinstance(val, dict):  | 
|
978  | 
newval = val  | 
|
979  | 
else:  | 
|
980  | 
newval = val.decode(encoding)  | 
|
981  | 
newkey = key.decode(encoding)  | 
|
982  | 
section.rename(key, newkey)  | 
|
983  | 
section[newkey] = newval  | 
|
984  | 
        # using ``call_on_sections`` allows us to modify section names
 | 
|
985  | 
self.walk(decode, call_on_sections=True)  | 
|
986  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
987  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
988  | 
def encode(self, encoding):  | 
989  | 
"""  | 
|
990  | 
        Encode all strings and values from unicode,
 | 
|
991  | 
        using the specified encoding.
 | 
|
992  | 
        
 | 
|
993  | 
        Works with subsections and list values.
 | 
|
994  | 
        Uses the ``walk`` method.
 | 
|
995  | 
        """
 | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
996  | 
warn('use of ``encode`` is deprecated.', DeprecationWarning)  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
997  | 
def encode(section, key, encoding=encoding):  | 
998  | 
""" """  | 
|
999  | 
val = section[key]  | 
|
1000  | 
if isinstance(val, (list, tuple)):  | 
|
1001  | 
newval = []  | 
|
1002  | 
for entry in val:  | 
|
1003  | 
newval.append(entry.encode(encoding))  | 
|
1004  | 
elif isinstance(val, dict):  | 
|
1005  | 
newval = val  | 
|
1006  | 
else:  | 
|
1007  | 
newval = val.encode(encoding)  | 
|
1008  | 
newkey = key.encode(encoding)  | 
|
1009  | 
section.rename(key, newkey)  | 
|
1010  | 
section[newkey] = newval  | 
|
1011  | 
self.walk(encode, call_on_sections=True)  | 
|
1012  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1013  | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
1014  | 
def istrue(self, key):  | 
1015  | 
"""A deprecated version of ``as_bool``."""  | 
|
1016  | 
warn('use of ``istrue`` is deprecated. Use ``as_bool`` method '  | 
|
1017  | 
'instead.', DeprecationWarning)  | 
|
1018  | 
return self.as_bool(key)  | 
|
1019  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1020  | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
1021  | 
def as_bool(self, key):  | 
1022  | 
"""  | 
|
1023  | 
        Accepts a key as input. The corresponding value must be a string or
 | 
|
1024  | 
        the objects (``True`` or 1) or (``False`` or 0). We allow 0 and 1 to
 | 
|
1025  | 
        retain compatibility with Python 2.2.
 | 
|
1026  | 
        
 | 
|
1027  | 
        If the string is one of  ``True``, ``On``, ``Yes``, or ``1`` it returns 
 | 
|
1028  | 
        ``True``.
 | 
|
1029  | 
        
 | 
|
1030  | 
        If the string is one of  ``False``, ``Off``, ``No``, or ``0`` it returns 
 | 
|
1031  | 
        ``False``.
 | 
|
1032  | 
        
 | 
|
1033  | 
        ``as_bool`` is not case sensitive.
 | 
|
1034  | 
        
 | 
|
1035  | 
        Any other input will raise a ``ValueError``.
 | 
|
1036  | 
        
 | 
|
1037  | 
        >>> a = ConfigObj()
 | 
|
1038  | 
        >>> a['a'] = 'fish'
 | 
|
1039  | 
        >>> a.as_bool('a')
 | 
|
1040  | 
        Traceback (most recent call last):
 | 
|
1041  | 
        ValueError: Value "fish" is neither True nor False
 | 
|
1042  | 
        >>> a['b'] = 'True'
 | 
|
1043  | 
        >>> a.as_bool('b')
 | 
|
1044  | 
        1
 | 
|
1045  | 
        >>> a['b'] = 'off'
 | 
|
1046  | 
        >>> a.as_bool('b')
 | 
|
1047  | 
        0
 | 
|
1048  | 
        """
 | 
|
1049  | 
val = self[key]  | 
|
1050  | 
if val == True:  | 
|
1051  | 
return True  | 
|
1052  | 
elif val == False:  | 
|
1053  | 
return False  | 
|
1054  | 
else:  | 
|
1055  | 
try:  | 
|
1056  | 
if not isinstance(val, StringTypes):  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1057  | 
                    # TODO: Why do we raise a KeyError here?
 | 
1058  | 
raise KeyError()  | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
1059  | 
else:  | 
1060  | 
return self.main._bools[val.lower()]  | 
|
1061  | 
except KeyError:  | 
|
1062  | 
raise ValueError('Value "%s" is neither True nor False' % val)  | 
|
1063  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1064  | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
1065  | 
def as_int(self, key):  | 
1066  | 
"""  | 
|
1067  | 
        A convenience method which coerces the specified value to an integer.
 | 
|
1068  | 
        
 | 
|
1069  | 
        If the value is an invalid literal for ``int``, a ``ValueError`` will
 | 
|
1070  | 
        be raised.
 | 
|
1071  | 
        
 | 
|
1072  | 
        >>> a = ConfigObj()
 | 
|
1073  | 
        >>> a['a'] = 'fish'
 | 
|
1074  | 
        >>> a.as_int('a')
 | 
|
1075  | 
        Traceback (most recent call last):
 | 
|
1076  | 
        ValueError: invalid literal for int(): fish
 | 
|
1077  | 
        >>> a['b'] = '1'
 | 
|
1078  | 
        >>> a.as_int('b')
 | 
|
1079  | 
        1
 | 
|
1080  | 
        >>> a['b'] = '3.2'
 | 
|
1081  | 
        >>> a.as_int('b')
 | 
|
1082  | 
        Traceback (most recent call last):
 | 
|
1083  | 
        ValueError: invalid literal for int(): 3.2
 | 
|
1084  | 
        """
 | 
|
1085  | 
return int(self[key])  | 
|
1086  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1087  | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
1088  | 
def as_float(self, key):  | 
1089  | 
"""  | 
|
1090  | 
        A convenience method which coerces the specified value to a float.
 | 
|
1091  | 
        
 | 
|
1092  | 
        If the value is an invalid literal for ``float``, a ``ValueError`` will
 | 
|
1093  | 
        be raised.
 | 
|
1094  | 
        
 | 
|
1095  | 
        >>> a = ConfigObj()
 | 
|
1096  | 
        >>> a['a'] = 'fish'
 | 
|
1097  | 
        >>> a.as_float('a')
 | 
|
1098  | 
        Traceback (most recent call last):
 | 
|
1099  | 
        ValueError: invalid literal for float(): fish
 | 
|
1100  | 
        >>> a['b'] = '1'
 | 
|
1101  | 
        >>> a.as_float('b')
 | 
|
1102  | 
        1.0
 | 
|
1103  | 
        >>> a['b'] = '3.2'
 | 
|
1104  | 
        >>> a.as_float('b')
 | 
|
1105  | 
        3.2000000000000002
 | 
|
1106  | 
        """
 | 
|
1107  | 
return float(self[key])  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1108  | 
|
1109  | 
||
1110  | 
def restore_default(self, key):  | 
|
1111  | 
"""  | 
|
1112  | 
        Restore (and return) default value for the specified key.
 | 
|
1113  | 
        
 | 
|
1114  | 
        This method will only work for a ConfigObj that was created
 | 
|
1115  | 
        with a configspec and has been validated.
 | 
|
1116  | 
        
 | 
|
1117  | 
        If there is no default value for this key, ``KeyError`` is raised.
 | 
|
1118  | 
        """
 | 
|
1119  | 
default = self.default_values[key]  | 
|
1120  | 
dict.__setitem__(self, key, default)  | 
|
1121  | 
if key not in self.defaults:  | 
|
1122  | 
self.defaults.append(key)  | 
|
1123  | 
return default  | 
|
1124  | 
||
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
1125  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1126  | 
def restore_defaults(self):  | 
1127  | 
"""  | 
|
1128  | 
        Recursively restore default values to all members
 | 
|
1129  | 
        that have them.
 | 
|
1130  | 
        
 | 
|
1131  | 
        This method will only work for a ConfigObj that was created
 | 
|
1132  | 
        with a configspec and has been validated.
 | 
|
1133  | 
        
 | 
|
1134  | 
        It doesn't delete or modify entries without default values.
 | 
|
1135  | 
        """
 | 
|
1136  | 
for key in self.default_values:  | 
|
1137  | 
self.restore_default(key)  | 
|
1138  | 
||
1139  | 
for section in self.sections:  | 
|
1140  | 
self[section].restore_defaults()  | 
|
1141  | 
||
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
1142  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1143  | 
class ConfigObj(Section):  | 
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
1144  | 
"""An object to read, create, and write config files."""  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1145  | 
|
1146  | 
_keyword = re.compile(r'''^ # line start  | 
|
1147  | 
        (\s*)                   # indentation
 | 
|
1148  | 
        (                       # keyword
 | 
|
1149  | 
            (?:".*?")|          # double quotes
 | 
|
1150  | 
            (?:'.*?')|          # single quotes
 | 
|
1151  | 
            (?:[^'"=].*?)       # no quotes
 | 
|
1152  | 
        )
 | 
|
1153  | 
        \s*=\s*                 # divider
 | 
|
1154  | 
        (.*)                    # value (including list values and comments)
 | 
|
1155  | 
        $   # line end
 | 
|
1156  | 
''',  | 
|
1157  | 
re.VERBOSE)  | 
|
1158  | 
||
1159  | 
_sectionmarker = re.compile(r'''^  | 
|
1160  | 
        (\s*)                     # 1: indentation
 | 
|
1161  | 
        ((?:\[\s*)+)              # 2: section marker open
 | 
|
1162  | 
        (                         # 3: section name open
 | 
|
1163  | 
            (?:"\s*\S.*?\s*")|    # at least one non-space with double quotes
 | 
|
1164  | 
            (?:'\s*\S.*?\s*')|    # at least one non-space with single quotes
 | 
|
1165  | 
            (?:[^'"\s].*?)        # at least one non-space unquoted
 | 
|
1166  | 
        )                         # section name close
 | 
|
1167  | 
        ((?:\s*\])+)              # 4: section marker close
 | 
|
1168  | 
        \s*(\#.*)?                # 5: optional comment
 | 
|
1169  | 
$''',  | 
|
1170  | 
re.VERBOSE)  | 
|
1171  | 
||
1172  | 
    # this regexp pulls list values out as a single string
 | 
|
1173  | 
    # or single values and comments
 | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
1174  | 
    # FIXME: this regex adds a '' to the end of comma terminated lists
 | 
1175  | 
    #   workaround in ``_handle_value``
 | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1176  | 
_valueexp = re.compile(r'''^  | 
1177  | 
        (?:
 | 
|
1178  | 
            (?:
 | 
|
1179  | 
                (
 | 
|
1180  | 
                    (?:
 | 
|
1181  | 
                        (?:
 | 
|
1182  | 
                            (?:".*?")|              # double quotes
 | 
|
1183  | 
                            (?:'.*?')|              # single quotes
 | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
1184  | 
                            (?:[^'",\#][^,\#]*?)    # unquoted
 | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1185  | 
                        )
 | 
1186  | 
                        \s*,\s*                     # comma
 | 
|
1187  | 
                    )*      # match all list items ending in a comma (if any)
 | 
|
1188  | 
                )
 | 
|
1189  | 
                (
 | 
|
1190  | 
                    (?:".*?")|                      # double quotes
 | 
|
1191  | 
                    (?:'.*?')|                      # single quotes
 | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
1192  | 
                    (?:[^'",\#\s][^,]*?)|           # unquoted
 | 
1193  | 
                    (?:(?<!,))                      # Empty value
 | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1194  | 
                )?          # last item in a list - or string value
 | 
1195  | 
            )|
 | 
|
1196  | 
            (,)             # alternatively a single comma - empty list
 | 
|
1197  | 
        )
 | 
|
1198  | 
        \s*(\#.*)?          # optional comment
 | 
|
1199  | 
$''',  | 
|
1200  | 
re.VERBOSE)  | 
|
1201  | 
||
1202  | 
    # use findall to get the members of a list value
 | 
|
1203  | 
_listvalueexp = re.compile(r'''  | 
|
1204  | 
        (
 | 
|
1205  | 
            (?:".*?")|          # double quotes
 | 
|
1206  | 
            (?:'.*?')|          # single quotes
 | 
|
1207  | 
            (?:[^'",\#].*?)       # unquoted
 | 
|
1208  | 
        )
 | 
|
1209  | 
        \s*,\s*                 # comma
 | 
|
1210  | 
''',  | 
|
1211  | 
re.VERBOSE)  | 
|
1212  | 
||
1213  | 
    # this regexp is used for the value
 | 
|
1214  | 
    # when lists are switched off
 | 
|
1215  | 
_nolistvalue = re.compile(r'''^  | 
|
1216  | 
        (
 | 
|
1217  | 
            (?:".*?")|          # double quotes
 | 
|
1218  | 
            (?:'.*?')|          # single quotes
 | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
1219  | 
            (?:[^'"\#].*?)|     # unquoted
 | 
1220  | 
            (?:)                # Empty value
 | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1221  | 
        )
 | 
1222  | 
        \s*(\#.*)?              # optional comment
 | 
|
1223  | 
$''',  | 
|
1224  | 
re.VERBOSE)  | 
|
1225  | 
||
1226  | 
    # regexes for finding triple quoted values on one line
 | 
|
1227  | 
_single_line_single = re.compile(r"^'''(.*?)'''\s*(#.*)?$")  | 
|
1228  | 
_single_line_double = re.compile(r'^"""(.*?)"""\s*(#.*)?$')  | 
|
1229  | 
_multi_line_single = re.compile(r"^(.*?)'''\s*(#.*)?$")  | 
|
1230  | 
_multi_line_double = re.compile(r'^(.*?)"""\s*(#.*)?$')  | 
|
1231  | 
||
1232  | 
_triple_quote = {  | 
|
1233  | 
"'''": (_single_line_single, _multi_line_single),  | 
|
1234  | 
'"""': (_single_line_double, _multi_line_double),  | 
|
1235  | 
    }
 | 
|
1236  | 
||
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
1237  | 
    # Used by the ``istrue`` Section method
 | 
1238  | 
_bools = {  | 
|
1239  | 
'yes': True, 'no': False,  | 
|
1240  | 
'on': True, 'off': False,  | 
|
1241  | 
'1': True, '0': False,  | 
|
1242  | 
'true': True, 'false': False,  | 
|
1243  | 
        }
 | 
|
1244  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1245  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1246  | 
def __init__(self, infile=None, options=None, **kwargs):  | 
1247  | 
"""  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1248  | 
        Parse a config file or create a config file object.
 | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1249  | 
        
 | 
1250  | 
        ``ConfigObj(infile=None, options=None, **kwargs)``
 | 
|
1251  | 
        """
 | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1252  | 
        # init the superclass
 | 
1253  | 
Section.__init__(self, self, 0, self)  | 
|
1254  | 
||
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1255  | 
if infile is None:  | 
1256  | 
infile = []  | 
|
1257  | 
if options is None:  | 
|
1258  | 
options = {}  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
1259  | 
else:  | 
1260  | 
options = dict(options)  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1261  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1262  | 
        # keyword arguments take precedence over an options dictionary
 | 
1263  | 
options.update(kwargs)  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1264  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1265  | 
defaults = OPTION_DEFAULTS.copy()  | 
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
1266  | 
        # TODO: check the values too.
 | 
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1267  | 
for entry in options:  | 
1268  | 
if entry not in defaults:  | 
|
1269  | 
raise TypeError('Unrecognised option "%s".' % entry)  | 
|
1270  | 
||
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
1271  | 
        # Add any explicit options to the defaults
 | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1272  | 
defaults.update(options)  | 
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1273  | 
self._initialise(defaults)  | 
1274  | 
configspec = defaults['configspec']  | 
|
1275  | 
self._original_configspec = configspec  | 
|
1276  | 
self._load(infile, configspec)  | 
|
1277  | 
||
1278  | 
||
1279  | 
def _load(self, infile, configspec):  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1280  | 
if isinstance(infile, StringTypes):  | 
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
1281  | 
self.filename = infile  | 
1282  | 
if os.path.isfile(infile):  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1283  | 
h = open(infile, 'rb')  | 
1284  | 
infile = h.read() or []  | 
|
1285  | 
h.close()  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1286  | 
elif self.file_error:  | 
1287  | 
                # raise an error if the file doesn't exist
 | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1288  | 
raise IOError('Config file not found: "%s".' % self.filename)  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1289  | 
else:  | 
1290  | 
                # file doesn't already exist
 | 
|
1291  | 
if self.create_empty:  | 
|
1292  | 
                    # this is a good test that the filename specified
 | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1293  | 
                    # isn't impossible - like on a non-existent device
 | 
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
1294  | 
h = open(infile, 'w')  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1295  | 
h.write('')  | 
1296  | 
h.close()  | 
|
1297  | 
infile = []  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1298  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1299  | 
elif isinstance(infile, (list, tuple)):  | 
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
1300  | 
infile = list(infile)  | 
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1301  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1302  | 
elif isinstance(infile, dict):  | 
1303  | 
            # initialise self
 | 
|
1304  | 
            # the Section class handles creating subsections
 | 
|
1305  | 
if isinstance(infile, ConfigObj):  | 
|
1306  | 
                # get a copy of our ConfigObj
 | 
|
1307  | 
infile = infile.dict()  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1308  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1309  | 
for entry in infile:  | 
1310  | 
self[entry] = infile[entry]  | 
|
1311  | 
del self._errors  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1312  | 
|
1313  | 
if configspec is not None:  | 
|
1314  | 
self._handle_configspec(configspec)  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1315  | 
else:  | 
1316  | 
self.configspec = None  | 
|
1317  | 
            return
 | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1318  | 
|
| 
3239.1.2
by Matt Nordhoff
 Restore hasattr -> getattr  | 
1319  | 
elif getattr(infile, 'read', None) is not None:  | 
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
1320  | 
            # This supports file like objects
 | 
1321  | 
infile = infile.read() or []  | 
|
1322  | 
            # needs splitting into lines - but needs doing *after* decoding
 | 
|
1323  | 
            # in case it's not an 8 bit encoding
 | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1324  | 
else:  | 
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1325  | 
raise TypeError('infile must be a filename, file like object, or list of lines.')  | 
1326  | 
||
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
1327  | 
if infile:  | 
1328  | 
            # don't do it for the empty ConfigObj
 | 
|
1329  | 
infile = self._handle_bom(infile)  | 
|
1330  | 
            # infile is now *always* a list
 | 
|
1331  | 
            #
 | 
|
1332  | 
            # Set the newlines attribute (first line ending it finds)
 | 
|
1333  | 
            # and strip trailing '\n' or '\r' from lines
 | 
|
1334  | 
for line in infile:  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
1335  | 
if (not line) or (line[-1] not in ('\r', '\n', '\r\n')):  | 
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
1336  | 
                    continue
 | 
1337  | 
for end in ('\r\n', '\n', '\r'):  | 
|
1338  | 
if line.endswith(end):  | 
|
1339  | 
self.newlines = end  | 
|
1340  | 
                        break
 | 
|
1341  | 
                break
 | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1342  | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
1343  | 
infile = [line.rstrip('\r\n') for line in infile]  | 
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1344  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1345  | 
self._parse(infile)  | 
1346  | 
        # if we had any errors, now is the time to raise them
 | 
|
1347  | 
if self._errors:  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
1348  | 
info = "at line %s." % self._errors[0].line_number  | 
1349  | 
if len(self._errors) > 1:  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1350  | 
msg = "Parsing failed with several errors.\nFirst error %s" % info  | 
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
1351  | 
error = ConfigObjError(msg)  | 
1352  | 
else:  | 
|
1353  | 
error = self._errors[0]  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1354  | 
            # set the errors attribute; it's a list of tuples:
 | 
1355  | 
            # (error_type, message, line_number)
 | 
|
1356  | 
error.errors = self._errors  | 
|
1357  | 
            # set the config attribute
 | 
|
1358  | 
error.config = self  | 
|
1359  | 
raise error  | 
|
1360  | 
        # delete private attributes
 | 
|
1361  | 
del self._errors  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1362  | 
|
1363  | 
if configspec is None:  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1364  | 
self.configspec = None  | 
1365  | 
else:  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1366  | 
self._handle_configspec(configspec)  | 
1367  | 
||
1368  | 
||
1369  | 
def _initialise(self, options=None):  | 
|
1370  | 
if options is None:  | 
|
1371  | 
options = OPTION_DEFAULTS  | 
|
1372  | 
||
1373  | 
        # initialise a few variables
 | 
|
1374  | 
self.filename = None  | 
|
1375  | 
self._errors = []  | 
|
1376  | 
self.raise_errors = options['raise_errors']  | 
|
1377  | 
self.interpolation = options['interpolation']  | 
|
1378  | 
self.list_values = options['list_values']  | 
|
1379  | 
self.create_empty = options['create_empty']  | 
|
1380  | 
self.file_error = options['file_error']  | 
|
1381  | 
self.stringify = options['stringify']  | 
|
1382  | 
self.indent_type = options['indent_type']  | 
|
1383  | 
self.encoding = options['encoding']  | 
|
1384  | 
self.default_encoding = options['default_encoding']  | 
|
1385  | 
self.BOM = False  | 
|
1386  | 
self.newlines = None  | 
|
1387  | 
self.write_empty_values = options['write_empty_values']  | 
|
1388  | 
self.unrepr = options['unrepr']  | 
|
1389  | 
||
1390  | 
self.initial_comment = []  | 
|
1391  | 
self.final_comment = []  | 
|
1392  | 
self.configspec = {}  | 
|
1393  | 
||
1394  | 
        # Clear section attributes as well
 | 
|
1395  | 
Section._initialise(self)  | 
|
1396  | 
||
1397  | 
||
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
1398  | 
def __repr__(self):  | 
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1399  | 
return ('ConfigObj({%s})' %  | 
1400  | 
', '.join([('%s: %s' % (repr(key), repr(self[key])))  | 
|
1401  | 
for key in (self.scalars + self.sections)]))  | 
|
1402  | 
||
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
1403  | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
1404  | 
def _handle_bom(self, infile):  | 
1405  | 
"""  | 
|
1406  | 
        Handle any BOM, and decode if necessary.
 | 
|
1407  | 
        
 | 
|
1408  | 
        If an encoding is specified, that *must* be used - but the BOM should
 | 
|
1409  | 
        still be removed (and the BOM attribute set).
 | 
|
1410  | 
        
 | 
|
1411  | 
        (If the encoding is wrongly specified, then a BOM for an alternative
 | 
|
1412  | 
        encoding won't be discovered or removed.)
 | 
|
1413  | 
        
 | 
|
1414  | 
        If an encoding is not specified, UTF8 or UTF16 BOM will be detected and
 | 
|
1415  | 
        removed. The BOM attribute will be set. UTF16 will be decoded to
 | 
|
1416  | 
        unicode.
 | 
|
1417  | 
        
 | 
|
1418  | 
        NOTE: This method must not be called with an empty ``infile``.
 | 
|
1419  | 
        
 | 
|
1420  | 
        Specifying the *wrong* encoding is likely to cause a
 | 
|
1421  | 
        ``UnicodeDecodeError``.
 | 
|
1422  | 
        
 | 
|
1423  | 
        ``infile`` must always be returned as a list of lines, but may be
 | 
|
1424  | 
        passed in as a single string.
 | 
|
1425  | 
        """
 | 
|
1426  | 
if ((self.encoding is not None) and  | 
|
1427  | 
(self.encoding.lower() not in BOM_LIST)):  | 
|
1428  | 
            # No need to check for a BOM
 | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
1429  | 
            # the encoding specified doesn't have one
 | 
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
1430  | 
            # just decode
 | 
1431  | 
return self._decode(infile, self.encoding)  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1432  | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
1433  | 
if isinstance(infile, (list, tuple)):  | 
1434  | 
line = infile[0]  | 
|
1435  | 
else:  | 
|
1436  | 
line = infile  | 
|
1437  | 
if self.encoding is not None:  | 
|
1438  | 
            # encoding explicitly supplied
 | 
|
1439  | 
            # And it could have an associated BOM
 | 
|
1440  | 
            # TODO: if encoding is just UTF16 - we ought to check for both
 | 
|
1441  | 
            # TODO: big endian and little endian versions.
 | 
|
1442  | 
enc = BOM_LIST[self.encoding.lower()]  | 
|
1443  | 
if enc == 'utf_16':  | 
|
1444  | 
                # For UTF16 we try big endian and little endian
 | 
|
1445  | 
for BOM, (encoding, final_encoding) in BOMS.items():  | 
|
1446  | 
if not final_encoding:  | 
|
1447  | 
                        # skip UTF8
 | 
|
1448  | 
                        continue
 | 
|
1449  | 
if infile.startswith(BOM):  | 
|
1450  | 
                        ### BOM discovered
 | 
|
1451  | 
                        ##self.BOM = True
 | 
|
1452  | 
                        # Don't need to remove BOM
 | 
|
1453  | 
return self._decode(infile, encoding)  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1454  | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
1455  | 
                # If we get this far, will *probably* raise a DecodeError
 | 
1456  | 
                # As it doesn't appear to start with a BOM
 | 
|
1457  | 
return self._decode(infile, self.encoding)  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1458  | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
1459  | 
            # Must be UTF8
 | 
1460  | 
BOM = BOM_SET[enc]  | 
|
1461  | 
if not line.startswith(BOM):  | 
|
1462  | 
return self._decode(infile, self.encoding)  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1463  | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
1464  | 
newline = line[len(BOM):]  | 
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1465  | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
1466  | 
            # BOM removed
 | 
1467  | 
if isinstance(infile, (list, tuple)):  | 
|
1468  | 
infile[0] = newline  | 
|
1469  | 
else:  | 
|
1470  | 
infile = newline  | 
|
1471  | 
self.BOM = True  | 
|
1472  | 
return self._decode(infile, self.encoding)  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1473  | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
1474  | 
        # No encoding specified - so we need to check for UTF8/UTF16
 | 
1475  | 
for BOM, (encoding, final_encoding) in BOMS.items():  | 
|
1476  | 
if not line.startswith(BOM):  | 
|
1477  | 
                continue
 | 
|
1478  | 
else:  | 
|
1479  | 
                # BOM discovered
 | 
|
1480  | 
self.encoding = final_encoding  | 
|
1481  | 
if not final_encoding:  | 
|
1482  | 
self.BOM = True  | 
|
1483  | 
                    # UTF8
 | 
|
1484  | 
                    # remove BOM
 | 
|
1485  | 
newline = line[len(BOM):]  | 
|
1486  | 
if isinstance(infile, (list, tuple)):  | 
|
1487  | 
infile[0] = newline  | 
|
1488  | 
else:  | 
|
1489  | 
infile = newline  | 
|
1490  | 
                    # UTF8 - don't decode
 | 
|
1491  | 
if isinstance(infile, StringTypes):  | 
|
1492  | 
return infile.splitlines(True)  | 
|
1493  | 
else:  | 
|
1494  | 
return infile  | 
|
1495  | 
                # UTF16 - have to decode
 | 
|
1496  | 
return self._decode(infile, encoding)  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1497  | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
1498  | 
        # No BOM discovered and no encoding specified, just return
 | 
1499  | 
if isinstance(infile, StringTypes):  | 
|
1500  | 
            # infile read from a file will be a single string
 | 
|
1501  | 
return infile.splitlines(True)  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1502  | 
return infile  | 
1503  | 
||
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
1504  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
1505  | 
def _a_to_u(self, aString):  | 
1506  | 
"""Decode ASCII strings to unicode if a self.encoding is specified."""  | 
|
1507  | 
if self.encoding:  | 
|
1508  | 
return aString.decode('ascii')  | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
1509  | 
else:  | 
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
1510  | 
return aString  | 
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
1511  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1512  | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
1513  | 
def _decode(self, infile, encoding):  | 
1514  | 
"""  | 
|
1515  | 
        Decode infile to unicode. Using the specified encoding.
 | 
|
1516  | 
        
 | 
|
1517  | 
        if is a string, it also needs converting to a list.
 | 
|
1518  | 
        """
 | 
|
1519  | 
if isinstance(infile, StringTypes):  | 
|
1520  | 
            # can't be unicode
 | 
|
1521  | 
            # NOTE: Could raise a ``UnicodeDecodeError``
 | 
|
1522  | 
return infile.decode(encoding).splitlines(True)  | 
|
1523  | 
for i, line in enumerate(infile):  | 
|
1524  | 
if not isinstance(line, unicode):  | 
|
1525  | 
                # NOTE: The isinstance test here handles mixed lists of unicode/string
 | 
|
1526  | 
                # NOTE: But the decode will break on any non-string values
 | 
|
1527  | 
                # NOTE: Or could raise a ``UnicodeDecodeError``
 | 
|
1528  | 
infile[i] = line.decode(encoding)  | 
|
1529  | 
return infile  | 
|
1530  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1531  | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
1532  | 
def _decode_element(self, line):  | 
1533  | 
"""Decode element to unicode if necessary."""  | 
|
1534  | 
if not self.encoding:  | 
|
1535  | 
return line  | 
|
1536  | 
if isinstance(line, str) and self.default_encoding:  | 
|
1537  | 
return line.decode(self.default_encoding)  | 
|
1538  | 
return line  | 
|
1539  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1540  | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
1541  | 
def _str(self, value):  | 
1542  | 
"""  | 
|
1543  | 
        Used by ``stringify`` within validate, to turn non-string values
 | 
|
1544  | 
        into strings.
 | 
|
1545  | 
        """
 | 
|
1546  | 
if not isinstance(value, StringTypes):  | 
|
1547  | 
return str(value)  | 
|
1548  | 
else:  | 
|
1549  | 
return value  | 
|
1550  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1551  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1552  | 
def _parse(self, infile):  | 
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
1553  | 
"""Actually parse the config file."""  | 
1554  | 
temp_list_values = self.list_values  | 
|
1555  | 
if self.unrepr:  | 
|
1556  | 
self.list_values = False  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1557  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1558  | 
comment_list = []  | 
1559  | 
done_start = False  | 
|
1560  | 
this_section = self  | 
|
1561  | 
maxline = len(infile) - 1  | 
|
1562  | 
cur_index = -1  | 
|
1563  | 
reset_comment = False  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1564  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1565  | 
while cur_index < maxline:  | 
1566  | 
if reset_comment:  | 
|
1567  | 
comment_list = []  | 
|
1568  | 
cur_index += 1  | 
|
1569  | 
line = infile[cur_index]  | 
|
1570  | 
sline = line.strip()  | 
|
1571  | 
            # do we have anything on the line ?
 | 
|
1572  | 
if not sline or sline.startswith('#'):  | 
|
1573  | 
reset_comment = False  | 
|
1574  | 
comment_list.append(line)  | 
|
1575  | 
                continue
 | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1576  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1577  | 
if not done_start:  | 
1578  | 
                # preserve initial comment
 | 
|
1579  | 
self.initial_comment = comment_list  | 
|
1580  | 
comment_list = []  | 
|
1581  | 
done_start = True  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1582  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1583  | 
reset_comment = True  | 
1584  | 
            # first we check if it's a section marker
 | 
|
1585  | 
mat = self._sectionmarker.match(line)  | 
|
1586  | 
if mat is not None:  | 
|
1587  | 
                # is a section line
 | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1588  | 
(indent, sect_open, sect_name, sect_close, comment) = mat.groups()  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1589  | 
if indent and (self.indent_type is None):  | 
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
1590  | 
self.indent_type = indent  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1591  | 
cur_depth = sect_open.count('[')  | 
1592  | 
if cur_depth != sect_close.count(']'):  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1593  | 
self._handle_error("Cannot compute the section depth at line %s.",  | 
1594  | 
NestingError, infile, cur_index)  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1595  | 
                    continue
 | 
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1596  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1597  | 
if cur_depth < this_section.depth:  | 
1598  | 
                    # the new section is dropping back to a previous level
 | 
|
1599  | 
try:  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1600  | 
parent = self._match_depth(this_section,  | 
1601  | 
cur_depth).parent  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1602  | 
except SyntaxError:  | 
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1603  | 
self._handle_error("Cannot compute nesting level at line %s.",  | 
1604  | 
NestingError, infile, cur_index)  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1605  | 
                        continue
 | 
1606  | 
elif cur_depth == this_section.depth:  | 
|
1607  | 
                    # the new section is a sibling of the current section
 | 
|
1608  | 
parent = this_section.parent  | 
|
1609  | 
elif cur_depth == this_section.depth + 1:  | 
|
1610  | 
                    # the new section is a child the current section
 | 
|
1611  | 
parent = this_section  | 
|
1612  | 
else:  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1613  | 
self._handle_error("Section too nested at line %s.",  | 
1614  | 
NestingError, infile, cur_index)  | 
|
1615  | 
||
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1616  | 
sect_name = self._unquote(sect_name)  | 
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
1617  | 
if parent.has_key(sect_name):  | 
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1618  | 
self._handle_error('Duplicate section name at line %s.',  | 
1619  | 
DuplicateError, infile, cur_index)  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1620  | 
                    continue
 | 
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1621  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1622  | 
                # create the new section
 | 
1623  | 
this_section = Section(  | 
|
1624  | 
parent,  | 
|
1625  | 
cur_depth,  | 
|
1626  | 
self,  | 
|
1627  | 
name=sect_name)  | 
|
1628  | 
parent[sect_name] = this_section  | 
|
1629  | 
parent.inline_comments[sect_name] = comment  | 
|
1630  | 
parent.comments[sect_name] = comment_list  | 
|
1631  | 
                continue
 | 
|
1632  | 
            #
 | 
|
1633  | 
            # it's not a section marker,
 | 
|
1634  | 
            # so it should be a valid ``key = value`` line
 | 
|
1635  | 
mat = self._keyword.match(line)  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
1636  | 
if mat is None:  | 
1637  | 
                # it neither matched as a keyword
 | 
|
1638  | 
                # or a section marker
 | 
|
1639  | 
self._handle_error(  | 
|
1640  | 
'Invalid line at line "%s".',  | 
|
1641  | 
ParseError, infile, cur_index)  | 
|
1642  | 
else:  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1643  | 
                # is a keyword value
 | 
1644  | 
                # value will include any inline comment
 | 
|
1645  | 
(indent, key, value) = mat.groups()  | 
|
1646  | 
if indent and (self.indent_type is None):  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
1647  | 
self.indent_type = indent  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1648  | 
                # check for a multiline value
 | 
1649  | 
if value[:3] in ['"""', "'''"]:  | 
|
1650  | 
try:  | 
|
1651  | 
(value, comment, cur_index) = self._multiline(  | 
|
1652  | 
value, infile, cur_index, maxline)  | 
|
1653  | 
except SyntaxError:  | 
|
1654  | 
self._handle_error(  | 
|
1655  | 
'Parse error in value at line %s.',  | 
|
1656  | 
ParseError, infile, cur_index)  | 
|
1657  | 
                        continue
 | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
1658  | 
else:  | 
1659  | 
if self.unrepr:  | 
|
1660  | 
comment = ''  | 
|
1661  | 
try:  | 
|
1662  | 
value = unrepr(value)  | 
|
1663  | 
except Exception, e:  | 
|
1664  | 
if type(e) == UnknownType:  | 
|
1665  | 
msg = 'Unknown name or type in value at line %s.'  | 
|
1666  | 
else:  | 
|
1667  | 
msg = 'Parse error in value at line %s.'  | 
|
1668  | 
self._handle_error(msg, UnreprError, infile,  | 
|
1669  | 
cur_index)  | 
|
1670  | 
                                continue
 | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1671  | 
else:  | 
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
1672  | 
if self.unrepr:  | 
1673  | 
comment = ''  | 
|
1674  | 
try:  | 
|
1675  | 
value = unrepr(value)  | 
|
1676  | 
except Exception, e:  | 
|
1677  | 
if isinstance(e, UnknownType):  | 
|
1678  | 
msg = 'Unknown name or type in value at line %s.'  | 
|
1679  | 
else:  | 
|
1680  | 
msg = 'Parse error in value at line %s.'  | 
|
1681  | 
self._handle_error(msg, UnreprError, infile,  | 
|
1682  | 
cur_index)  | 
|
1683  | 
                            continue
 | 
|
1684  | 
else:  | 
|
1685  | 
                        # extract comment and lists
 | 
|
1686  | 
try:  | 
|
1687  | 
(value, comment) = self._handle_value(value)  | 
|
1688  | 
except SyntaxError:  | 
|
1689  | 
self._handle_error(  | 
|
1690  | 
'Parse error in value at line %s.',  | 
|
1691  | 
ParseError, infile, cur_index)  | 
|
1692  | 
                            continue
 | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1693  | 
                #
 | 
1694  | 
key = self._unquote(key)  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
1695  | 
if this_section.has_key(key):  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1696  | 
self._handle_error(  | 
1697  | 
'Duplicate keyword name at line %s.',  | 
|
1698  | 
DuplicateError, infile, cur_index)  | 
|
1699  | 
                    continue
 | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
1700  | 
                # add the key.
 | 
1701  | 
                # we set unrepr because if we have got this far we will never
 | 
|
1702  | 
                # be creating a new section
 | 
|
1703  | 
this_section.__setitem__(key, value, unrepr=True)  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1704  | 
this_section.inline_comments[key] = comment  | 
1705  | 
this_section.comments[key] = comment_list  | 
|
1706  | 
                continue
 | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
1707  | 
        #
 | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1708  | 
if self.indent_type is None:  | 
1709  | 
            # no indentation used, set the type accordingly
 | 
|
1710  | 
self.indent_type = ''  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1711  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1712  | 
        # preserve the final comment
 | 
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
1713  | 
if not self and not self.initial_comment:  | 
1714  | 
self.initial_comment = comment_list  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
1715  | 
elif not reset_comment:  | 
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
1716  | 
self.final_comment = comment_list  | 
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
1717  | 
self.list_values = temp_list_values  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1718  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1719  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1720  | 
def _match_depth(self, sect, depth):  | 
1721  | 
"""  | 
|
1722  | 
        Given a section and a depth level, walk back through the sections
 | 
|
1723  | 
        parents to see if the depth level matches a previous section.
 | 
|
1724  | 
        
 | 
|
1725  | 
        Return a reference to the right section,
 | 
|
1726  | 
        or raise a SyntaxError.
 | 
|
1727  | 
        """
 | 
|
1728  | 
while depth < sect.depth:  | 
|
1729  | 
if sect is sect.parent:  | 
|
1730  | 
                # we've reached the top level already
 | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1731  | 
raise SyntaxError()  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1732  | 
sect = sect.parent  | 
1733  | 
if sect.depth == depth:  | 
|
1734  | 
return sect  | 
|
1735  | 
        # shouldn't get here
 | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1736  | 
raise SyntaxError()  | 
1737  | 
||
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1738  | 
|
1739  | 
def _handle_error(self, text, ErrorClass, infile, cur_index):  | 
|
1740  | 
"""  | 
|
1741  | 
        Handle an error according to the error settings.
 | 
|
1742  | 
        
 | 
|
1743  | 
        Either raise the error or store it.
 | 
|
1744  | 
        The error will have occured at ``cur_index``
 | 
|
1745  | 
        """
 | 
|
1746  | 
line = infile[cur_index]  | 
|
| 
2900.1.2
by Vincent Ladeuil
 Fix 149019 by using a proper line number when reporting errors.  | 
1747  | 
cur_index += 1  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1748  | 
message = text % cur_index  | 
1749  | 
error = ErrorClass(message, cur_index, line)  | 
|
1750  | 
if self.raise_errors:  | 
|
1751  | 
            # raise the error - parsing stops here
 | 
|
1752  | 
raise error  | 
|
1753  | 
        # store the error
 | 
|
1754  | 
        # reraise when parsing has finished
 | 
|
1755  | 
self._errors.append(error)  | 
|
1756  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1757  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1758  | 
def _unquote(self, value):  | 
1759  | 
"""Return an unquoted version of a value"""  | 
|
1760  | 
if (value[0] == value[-1]) and (value[0] in ('"', "'")):  | 
|
1761  | 
value = value[1:-1]  | 
|
1762  | 
return value  | 
|
1763  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1764  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1765  | 
def _quote(self, value, multiline=True):  | 
1766  | 
"""  | 
|
1767  | 
        Return a safely quoted version of a value.
 | 
|
1768  | 
        
 | 
|
1769  | 
        Raise a ConfigObjError if the value cannot be safely quoted.
 | 
|
1770  | 
        If multiline is ``True`` (default) then use triple quotes
 | 
|
1771  | 
        if necessary.
 | 
|
1772  | 
        
 | 
|
1773  | 
        Don't quote values that don't need it.
 | 
|
1774  | 
        Recursively quote members of a list and return a comma joined list.
 | 
|
1775  | 
        Multiline is ``False`` for lists.
 | 
|
1776  | 
        Obey list syntax for empty and single member lists.
 | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
1777  | 
        
 | 
1778  | 
        If ``list_values=False`` then the value is only quoted if it contains
 | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1779  | 
        a ``\n`` (is multiline) or '#'.
 | 
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
1780  | 
        
 | 
1781  | 
        If ``write_empty_values`` is set, and the value is an empty string, it
 | 
|
1782  | 
        won't be quoted.
 | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1783  | 
        """
 | 
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
1784  | 
if multiline and self.write_empty_values and value == '':  | 
1785  | 
            # Only if multiline is set, so that it is used for values not
 | 
|
1786  | 
            # keys, and not values that are part of a list
 | 
|
1787  | 
return ''  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1788  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
1789  | 
if multiline and isinstance(value, (list, tuple)):  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1790  | 
if not value:  | 
1791  | 
return ','  | 
|
1792  | 
elif len(value) == 1:  | 
|
1793  | 
return self._quote(value[0], multiline=False) + ','  | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
1794  | 
return ', '.join([self._quote(val, multiline=False)  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1795  | 
for val in value])  | 
1796  | 
if not isinstance(value, StringTypes):  | 
|
1797  | 
if self.stringify:  | 
|
1798  | 
value = str(value)  | 
|
1799  | 
else:  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1800  | 
raise TypeError('Value "%s" is not a string.' % value)  | 
1801  | 
||
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1802  | 
if not value:  | 
1803  | 
return '""'  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1804  | 
|
1805  | 
no_lists_no_quotes = not self.list_values and '\n' not in value and '#' not in value  | 
|
1806  | 
need_triple = multiline and ((("'" in value) and ('"' in value)) or ('\n' in value ))  | 
|
1807  | 
hash_triple_quote = multiline and not need_triple and ("'" in value) and ('"' in value) and ('#' in value)  | 
|
1808  | 
check_for_single = (no_lists_no_quotes or not need_triple) and not hash_triple_quote  | 
|
1809  | 
||
1810  | 
if check_for_single:  | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
1811  | 
if not self.list_values:  | 
1812  | 
                # we don't quote if ``list_values=False``
 | 
|
1813  | 
quot = noquot  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1814  | 
            # for normal values either single or double quotes will do
 | 
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
1815  | 
elif '\n' in value:  | 
1816  | 
                # will only happen if multiline is off - e.g. '\n' in key
 | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1817  | 
raise ConfigObjError('Value "%s" cannot be safely quoted.' % value)  | 
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
1818  | 
elif ((value[0] not in wspace_plus) and  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1819  | 
(value[-1] not in wspace_plus) and  | 
1820  | 
(',' not in value)):  | 
|
1821  | 
quot = noquot  | 
|
1822  | 
else:  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1823  | 
quot = self._get_single_quote(value)  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1824  | 
else:  | 
1825  | 
            # if value has '\n' or "'" *and* '"', it will need triple quotes
 | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1826  | 
quot = self._get_triple_quote(value)  | 
1827  | 
||
1828  | 
if quot == noquot and '#' in value and self.list_values:  | 
|
1829  | 
quot = self._get_single_quote(value)  | 
|
1830  | 
||
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1831  | 
return quot % value  | 
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1832  | 
|
1833  | 
||
1834  | 
def _get_single_quote(self, value):  | 
|
1835  | 
if ("'" in value) and ('"' in value):  | 
|
1836  | 
raise ConfigObjError('Value "%s" cannot be safely quoted.' % value)  | 
|
1837  | 
elif '"' in value:  | 
|
1838  | 
quot = squot  | 
|
1839  | 
else:  | 
|
1840  | 
quot = dquot  | 
|
1841  | 
return quot  | 
|
1842  | 
||
1843  | 
||
1844  | 
def _get_triple_quote(self, value):  | 
|
1845  | 
if (value.find('"""') != -1) and (value.find("'''") != -1):  | 
|
1846  | 
raise ConfigObjError('Value "%s" cannot be safely quoted.' % value)  | 
|
1847  | 
if value.find('"""') == -1:  | 
|
1848  | 
quot = tdquot  | 
|
1849  | 
else:  | 
|
1850  | 
quot = tsquot  | 
|
1851  | 
return quot  | 
|
1852  | 
||
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1853  | 
|
1854  | 
def _handle_value(self, value):  | 
|
1855  | 
"""  | 
|
1856  | 
        Given a value string, unquote, remove comment,
 | 
|
1857  | 
        handle lists. (including empty and single member lists)
 | 
|
1858  | 
        """
 | 
|
1859  | 
        # do we look for lists in values ?
 | 
|
1860  | 
if not self.list_values:  | 
|
1861  | 
mat = self._nolistvalue.match(value)  | 
|
1862  | 
if mat is None:  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1863  | 
raise SyntaxError()  | 
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
1864  | 
            # NOTE: we don't unquote here
 | 
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
1865  | 
return mat.groups()  | 
1866  | 
        #
 | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1867  | 
mat = self._valueexp.match(value)  | 
1868  | 
if mat is None:  | 
|
1869  | 
            # the value is badly constructed, probably badly quoted,
 | 
|
1870  | 
            # or an invalid list
 | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1871  | 
raise SyntaxError()  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1872  | 
(list_values, single, empty_list, comment) = mat.groups()  | 
1873  | 
if (list_values == '') and (single is None):  | 
|
1874  | 
            # change this if you want to accept empty values
 | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1875  | 
raise SyntaxError()  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1876  | 
        # NOTE: note there is no error handling from here if the regex
 | 
1877  | 
        # is wrong: then incorrect values will slip through
 | 
|
1878  | 
if empty_list is not None:  | 
|
1879  | 
            # the single comma - meaning an empty list
 | 
|
1880  | 
return ([], comment)  | 
|
1881  | 
if single is not None:  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
1882  | 
            # handle empty values
 | 
1883  | 
if list_values and not single:  | 
|
1884  | 
                # FIXME: the '' is a workaround because our regex now matches
 | 
|
1885  | 
                #   '' at the end of a list if it has a trailing comma
 | 
|
1886  | 
single = None  | 
|
1887  | 
else:  | 
|
1888  | 
single = single or '""'  | 
|
1889  | 
single = self._unquote(single)  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1890  | 
if list_values == '':  | 
1891  | 
            # not a list value
 | 
|
1892  | 
return (single, comment)  | 
|
1893  | 
the_list = self._listvalueexp.findall(list_values)  | 
|
1894  | 
the_list = [self._unquote(val) for val in the_list]  | 
|
1895  | 
if single is not None:  | 
|
1896  | 
the_list += [single]  | 
|
1897  | 
return (the_list, comment)  | 
|
1898  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1899  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1900  | 
def _multiline(self, value, infile, cur_index, maxline):  | 
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
1901  | 
"""Extract the value, where we are in a multiline situation."""  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1902  | 
quot = value[:3]  | 
1903  | 
newvalue = value[3:]  | 
|
1904  | 
single_line = self._triple_quote[quot][0]  | 
|
1905  | 
multi_line = self._triple_quote[quot][1]  | 
|
1906  | 
mat = single_line.match(value)  | 
|
1907  | 
if mat is not None:  | 
|
1908  | 
retval = list(mat.groups())  | 
|
1909  | 
retval.append(cur_index)  | 
|
1910  | 
return retval  | 
|
1911  | 
elif newvalue.find(quot) != -1:  | 
|
1912  | 
            # somehow the triple quote is missing
 | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1913  | 
raise SyntaxError()  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1914  | 
        #
 | 
1915  | 
while cur_index < maxline:  | 
|
1916  | 
cur_index += 1  | 
|
1917  | 
newvalue += '\n'  | 
|
1918  | 
line = infile[cur_index]  | 
|
1919  | 
if line.find(quot) == -1:  | 
|
1920  | 
newvalue += line  | 
|
1921  | 
else:  | 
|
1922  | 
                # end of multiline, process it
 | 
|
1923  | 
                break
 | 
|
1924  | 
else:  | 
|
1925  | 
            # we've got to the end of the config, oops...
 | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1926  | 
raise SyntaxError()  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1927  | 
mat = multi_line.match(line)  | 
1928  | 
if mat is None:  | 
|
1929  | 
            # a badly formed line
 | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1930  | 
raise SyntaxError()  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1931  | 
(value, comment) = mat.groups()  | 
1932  | 
return (newvalue + value, comment, cur_index)  | 
|
1933  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1934  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1935  | 
def _handle_configspec(self, configspec):  | 
1936  | 
"""Parse the configspec."""  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
1937  | 
        # FIXME: Should we check that the configspec was created with the 
 | 
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1938  | 
        #        correct settings ? (i.e. ``list_values=False``)
 | 
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
1939  | 
if not isinstance(configspec, ConfigObj):  | 
1940  | 
try:  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1941  | 
configspec = ConfigObj(configspec,  | 
1942  | 
raise_errors=True,  | 
|
1943  | 
file_error=True,  | 
|
1944  | 
list_values=False)  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
1945  | 
except ConfigObjError, e:  | 
1946  | 
                # FIXME: Should these errors have a reference
 | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1947  | 
                #        to the already parsed ConfigObj ?
 | 
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
1948  | 
raise ConfigspecError('Parsing configspec failed: %s' % e)  | 
1949  | 
except IOError, e:  | 
|
1950  | 
raise IOError('Reading configspec failed: %s' % e)  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1951  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1952  | 
self._set_configspec_value(configspec, self)  | 
1953  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1954  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1955  | 
def _set_configspec_value(self, configspec, section):  | 
1956  | 
"""Used to recursively set configspec values."""  | 
|
1957  | 
if '__many__' in configspec.sections:  | 
|
1958  | 
section.configspec['__many__'] = configspec['__many__']  | 
|
1959  | 
if len(configspec.sections) > 1:  | 
|
1960  | 
                # FIXME: can we supply any useful information here ?
 | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1961  | 
raise RepeatSectionError()  | 
1962  | 
||
| 
3239.1.2
by Matt Nordhoff
 Restore hasattr -> getattr  | 
1963  | 
if getattr(configspec, 'initial_comment', None) is not None:  | 
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
1964  | 
section._configspec_initial_comment = configspec.initial_comment  | 
1965  | 
section._configspec_final_comment = configspec.final_comment  | 
|
1966  | 
section._configspec_encoding = configspec.encoding  | 
|
1967  | 
section._configspec_BOM = configspec.BOM  | 
|
1968  | 
section._configspec_newlines = configspec.newlines  | 
|
1969  | 
section._configspec_indent_type = configspec.indent_type  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1970  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1971  | 
for entry in configspec.scalars:  | 
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
1972  | 
section._configspec_comments[entry] = configspec.comments[entry]  | 
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1973  | 
section._configspec_inline_comments[entry] = configspec.inline_comments[entry]  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1974  | 
section.configspec[entry] = configspec[entry]  | 
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
1975  | 
section._order.append(entry)  | 
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1976  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1977  | 
for entry in configspec.sections:  | 
1978  | 
if entry == '__many__':  | 
|
1979  | 
                continue
 | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1980  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
1981  | 
section._cs_section_comments[entry] = configspec.comments[entry]  | 
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1982  | 
section._cs_section_inline_comments[entry] = configspec.inline_comments[entry]  | 
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
1983  | 
if not section.has_key(entry):  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1984  | 
section[entry] = {}  | 
1985  | 
self._set_configspec_value(configspec[entry], section[entry])  | 
|
1986  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1987  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1988  | 
def _handle_repeat(self, section, configspec):  | 
1989  | 
"""Dynamically assign configspec for repeated section."""  | 
|
1990  | 
try:  | 
|
1991  | 
section_keys = configspec.sections  | 
|
1992  | 
scalar_keys = configspec.scalars  | 
|
1993  | 
except AttributeError:  | 
|
1994  | 
section_keys = [entry for entry in configspec  | 
|
1995  | 
if isinstance(configspec[entry], dict)]  | 
|
1996  | 
scalar_keys = [entry for entry in configspec  | 
|
1997  | 
if not isinstance(configspec[entry], dict)]  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
1998  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
1999  | 
if '__many__' in section_keys and len(section_keys) > 1:  | 
2000  | 
            # FIXME: can we supply any useful information here ?
 | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
2001  | 
raise RepeatSectionError()  | 
2002  | 
||
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
2003  | 
scalars = {}  | 
2004  | 
sections = {}  | 
|
2005  | 
for entry in scalar_keys:  | 
|
2006  | 
val = configspec[entry]  | 
|
2007  | 
scalars[entry] = val  | 
|
2008  | 
for entry in section_keys:  | 
|
2009  | 
val = configspec[entry]  | 
|
2010  | 
if entry == '__many__':  | 
|
2011  | 
scalars[entry] = val  | 
|
2012  | 
                continue
 | 
|
2013  | 
sections[entry] = val  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
2014  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
2015  | 
section.configspec = scalars  | 
2016  | 
for entry in sections:  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
2017  | 
if not section.has_key(entry):  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
2018  | 
section[entry] = {}  | 
2019  | 
self._handle_repeat(section[entry], sections[entry])  | 
|
2020  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
2021  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
2022  | 
def _write_line(self, indent_string, entry, this_entry, comment):  | 
2023  | 
"""Write an individual line, for the write method"""  | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
2024  | 
        # NOTE: the calls to self._quote here handles non-StringType values.
 | 
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
2025  | 
if not self.unrepr:  | 
2026  | 
val = self._decode_element(self._quote(this_entry))  | 
|
2027  | 
else:  | 
|
2028  | 
val = repr(this_entry)  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
2029  | 
return '%s%s%s%s%s' % (indent_string,  | 
2030  | 
self._decode_element(self._quote(entry, multiline=False)),  | 
|
2031  | 
self._a_to_u(' = '),  | 
|
2032  | 
val,  | 
|
2033  | 
self._decode_element(comment))  | 
|
2034  | 
||
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
2035  | 
|
2036  | 
def _write_marker(self, indent_string, depth, entry, comment):  | 
|
2037  | 
"""Write a section marker line"""  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
2038  | 
return '%s%s%s%s%s' % (indent_string,  | 
2039  | 
self._a_to_u('[' * depth),  | 
|
2040  | 
self._quote(self._decode_element(entry), multiline=False),  | 
|
2041  | 
self._a_to_u(']' * depth),  | 
|
2042  | 
self._decode_element(comment))  | 
|
2043  | 
||
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
2044  | 
|
2045  | 
def _handle_comment(self, comment):  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
2046  | 
"""Deal with a comment."""  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
2047  | 
if not comment:  | 
2048  | 
return ''  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
2049  | 
start = self.indent_type  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
2050  | 
if not comment.startswith('#'):  | 
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
2051  | 
start += self._a_to_u(' # ')  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
2052  | 
return (start + comment)  | 
2053  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
2054  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
2055  | 
    # Public methods
 | 
2056  | 
||
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
2057  | 
def write(self, outfile=None, section=None):  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
2058  | 
"""  | 
2059  | 
        Write the current ConfigObj as a file
 | 
|
2060  | 
        
 | 
|
2061  | 
        tekNico: FIXME: use StringIO instead of real files
 | 
|
2062  | 
        
 | 
|
2063  | 
        >>> filename = a.filename
 | 
|
2064  | 
        >>> a.filename = 'test.ini'
 | 
|
2065  | 
        >>> a.write()
 | 
|
2066  | 
        >>> a.filename = filename
 | 
|
2067  | 
        >>> a == ConfigObj('test.ini', raise_errors=True)
 | 
|
2068  | 
        1
 | 
|
2069  | 
        """
 | 
|
2070  | 
if self.indent_type is None:  | 
|
2071  | 
            # this can be true if initialised from a dictionary
 | 
|
2072  | 
self.indent_type = DEFAULT_INDENT_TYPE  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
2073  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
2074  | 
out = []  | 
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
2075  | 
cs = self._a_to_u('#')  | 
2076  | 
csp = self._a_to_u('# ')  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
2077  | 
if section is None:  | 
2078  | 
int_val = self.interpolation  | 
|
2079  | 
self.interpolation = False  | 
|
2080  | 
section = self  | 
|
2081  | 
for line in self.initial_comment:  | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
2082  | 
line = self._decode_element(line)  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
2083  | 
stripped_line = line.strip()  | 
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
2084  | 
if stripped_line and not stripped_line.startswith(cs):  | 
2085  | 
line = csp + line  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
2086  | 
out.append(line)  | 
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
2087  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
2088  | 
indent_string = self.indent_type * section.depth  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
2089  | 
for entry in (section.scalars + section.sections):  | 
2090  | 
if entry in section.defaults:  | 
|
2091  | 
                # don't write out default values
 | 
|
2092  | 
                continue
 | 
|
2093  | 
for comment_line in section.comments[entry]:  | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
2094  | 
comment_line = self._decode_element(comment_line.lstrip())  | 
2095  | 
if comment_line and not comment_line.startswith(cs):  | 
|
2096  | 
comment_line = csp + comment_line  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
2097  | 
out.append(indent_string + comment_line)  | 
2098  | 
this_entry = section[entry]  | 
|
2099  | 
comment = self._handle_comment(section.inline_comments[entry])  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
2100  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
2101  | 
if isinstance(this_entry, dict):  | 
2102  | 
                # a section
 | 
|
2103  | 
out.append(self._write_marker(  | 
|
2104  | 
indent_string,  | 
|
2105  | 
this_entry.depth,  | 
|
2106  | 
entry,  | 
|
2107  | 
comment))  | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
2108  | 
out.extend(self.write(section=this_entry))  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
2109  | 
else:  | 
2110  | 
out.append(self._write_line(  | 
|
2111  | 
indent_string,  | 
|
2112  | 
entry,  | 
|
2113  | 
this_entry,  | 
|
2114  | 
comment))  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
2115  | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
2116  | 
if section is self:  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
2117  | 
for line in self.final_comment:  | 
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
2118  | 
line = self._decode_element(line)  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
2119  | 
stripped_line = line.strip()  | 
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
2120  | 
if stripped_line and not stripped_line.startswith(cs):  | 
2121  | 
line = csp + line  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
2122  | 
out.append(line)  | 
2123  | 
self.interpolation = int_val  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
2124  | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
2125  | 
if section is not self:  | 
2126  | 
return out  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
2127  | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
2128  | 
if (self.filename is None) and (outfile is None):  | 
2129  | 
            # output a list of lines
 | 
|
2130  | 
            # might need to encode
 | 
|
2131  | 
            # NOTE: This will *screw* UTF16, each line will start with the BOM
 | 
|
2132  | 
if self.encoding:  | 
|
2133  | 
out = [l.encode(self.encoding) for l in out]  | 
|
2134  | 
if (self.BOM and ((self.encoding is None) or  | 
|
2135  | 
(BOM_LIST.get(self.encoding.lower()) == 'utf_8'))):  | 
|
2136  | 
                # Add the UTF8 BOM
 | 
|
2137  | 
if not out:  | 
|
2138  | 
out.append('')  | 
|
2139  | 
out[0] = BOM_UTF8 + out[0]  | 
|
2140  | 
return out  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
2141  | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
2142  | 
        # Turn the list to a string, joined with correct newlines
 | 
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
2143  | 
newline = self.newlines or os.linesep  | 
2144  | 
output = self._a_to_u(newline).join(out)  | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
2145  | 
if self.encoding:  | 
2146  | 
output = output.encode(self.encoding)  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
2147  | 
if self.BOM and ((self.encoding is None) or match_utf8(self.encoding)):  | 
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
2148  | 
            # Add the UTF8 BOM
 | 
2149  | 
output = BOM_UTF8 + output  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
2150  | 
|
2151  | 
if not output.endswith(newline):  | 
|
2152  | 
output += newline  | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
2153  | 
if outfile is not None:  | 
2154  | 
outfile.write(output)  | 
|
2155  | 
else:  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
2156  | 
h = open(self.filename, 'wb')  | 
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
2157  | 
h.write(output)  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
2158  | 
h.close()  | 
2159  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
2160  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
2161  | 
def validate(self, validator, preserve_errors=False, copy=False,  | 
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
2162  | 
section=None):  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
2163  | 
"""  | 
2164  | 
        Test the ConfigObj against a configspec.
 | 
|
2165  | 
        
 | 
|
2166  | 
        It uses the ``validator`` object from *validate.py*.
 | 
|
2167  | 
        
 | 
|
2168  | 
        To run ``validate`` on the current ConfigObj, call: ::
 | 
|
2169  | 
        
 | 
|
2170  | 
            test = config.validate(validator)
 | 
|
2171  | 
        
 | 
|
2172  | 
        (Normally having previously passed in the configspec when the ConfigObj
 | 
|
2173  | 
        was created - you can dynamically assign a dictionary of checks to the
 | 
|
2174  | 
        ``configspec`` attribute of a section though).
 | 
|
2175  | 
        
 | 
|
2176  | 
        It returns ``True`` if everything passes, or a dictionary of
 | 
|
2177  | 
        pass/fails (True/False). If every member of a subsection passes, it
 | 
|
2178  | 
        will just have the value ``True``. (It also returns ``False`` if all
 | 
|
2179  | 
        members fail).
 | 
|
2180  | 
        
 | 
|
2181  | 
        In addition, it converts the values from strings to their native
 | 
|
2182  | 
        types if their checks pass (and ``stringify`` is set).
 | 
|
2183  | 
        
 | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
2184  | 
        If ``preserve_errors`` is ``True`` (``False`` is default) then instead
 | 
2185  | 
        of a marking a fail with a ``False``, it will preserve the actual
 | 
|
2186  | 
        exception object. This can contain info about the reason for failure.
 | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
2187  | 
        For example the ``VdtValueTooSmallError`` indicates that the value
 | 
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
2188  | 
        supplied was too small. If a value (or section) is missing it will
 | 
2189  | 
        still be marked as ``False``.
 | 
|
2190  | 
        
 | 
|
2191  | 
        You must have the validate module to use ``preserve_errors=True``.
 | 
|
2192  | 
        
 | 
|
2193  | 
        You can then use the ``flatten_errors`` function to turn your nested
 | 
|
2194  | 
        results dictionary into a flattened list of failures - useful for
 | 
|
2195  | 
        displaying meaningful error messages.
 | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
2196  | 
        """
 | 
2197  | 
if section is None:  | 
|
2198  | 
if self.configspec is None:  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
2199  | 
raise ValueError('No configspec supplied.')  | 
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
2200  | 
if preserve_errors:  | 
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
2201  | 
                # We do this once to remove a top level dependency on the validate module
 | 
2202  | 
                # Which makes importing configobj faster
 | 
|
2203  | 
from validate import VdtMissingValue  | 
|
2204  | 
self._vdtMissingValue = VdtMissingValue  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
2205  | 
section = self  | 
2206  | 
        #
 | 
|
2207  | 
spec_section = section.configspec  | 
|
| 
3239.1.2
by Matt Nordhoff
 Restore hasattr -> getattr  | 
2208  | 
if copy and getattr(section, '_configspec_initial_comment', None) is not None:  | 
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
2209  | 
section.initial_comment = section._configspec_initial_comment  | 
2210  | 
section.final_comment = section._configspec_final_comment  | 
|
2211  | 
section.encoding = section._configspec_encoding  | 
|
2212  | 
section.BOM = section._configspec_BOM  | 
|
2213  | 
section.newlines = section._configspec_newlines  | 
|
2214  | 
section.indent_type = section._configspec_indent_type  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
2215  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
2216  | 
if '__many__' in section.configspec:  | 
2217  | 
many = spec_section['__many__']  | 
|
2218  | 
            # dynamically assign the configspecs
 | 
|
2219  | 
            # for the sections below
 | 
|
2220  | 
for entry in section.sections:  | 
|
2221  | 
self._handle_repeat(section[entry], many)  | 
|
2222  | 
        #
 | 
|
2223  | 
out = {}  | 
|
2224  | 
ret_true = True  | 
|
2225  | 
ret_false = True  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
2226  | 
order = [k for k in section._order if k in spec_section]  | 
2227  | 
order += [k for k in spec_section if k not in order]  | 
|
2228  | 
for entry in order:  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
2229  | 
if entry == '__many__':  | 
2230  | 
                continue
 | 
|
2231  | 
if (not entry in section.scalars) or (entry in section.defaults):  | 
|
2232  | 
                # missing entries
 | 
|
2233  | 
                # or entries from defaults
 | 
|
2234  | 
missing = True  | 
|
2235  | 
val = None  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
2236  | 
if copy and not entry in section.scalars:  | 
2237  | 
                    # copy comments
 | 
|
2238  | 
section.comments[entry] = (  | 
|
2239  | 
section._configspec_comments.get(entry, []))  | 
|
2240  | 
section.inline_comments[entry] = (  | 
|
2241  | 
section._configspec_inline_comments.get(entry, ''))  | 
|
2242  | 
                #
 | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
2243  | 
else:  | 
2244  | 
missing = False  | 
|
2245  | 
val = section[entry]  | 
|
2246  | 
try:  | 
|
2247  | 
check = validator.check(spec_section[entry],  | 
|
2248  | 
val,  | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
2249  | 
missing=missing  | 
2250  | 
                                        )
 | 
|
2251  | 
except validator.baseErrorClass, e:  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
2252  | 
if not preserve_errors or isinstance(e, self._vdtMissingValue):  | 
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
2253  | 
out[entry] = False  | 
2254  | 
else:  | 
|
2255  | 
                    # preserve the error
 | 
|
2256  | 
out[entry] = e  | 
|
2257  | 
ret_false = False  | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
2258  | 
ret_true = False  | 
2259  | 
else:  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
2260  | 
try:  | 
2261  | 
section.default_values.pop(entry, None)  | 
|
2262  | 
except AttributeError:  | 
|
2263  | 
                    # For Python 2.2 compatibility
 | 
|
2264  | 
try:  | 
|
2265  | 
del section.default_values[entry]  | 
|
2266  | 
except KeyError:  | 
|
2267  | 
                        pass
 | 
|
2268  | 
||
| 
3239.1.2
by Matt Nordhoff
 Restore hasattr -> getattr  | 
2269  | 
if getattr(validator, 'get_default_value', None) is not None:  | 
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
2270  | 
try:  | 
2271  | 
section.default_values[entry] = validator.get_default_value(spec_section[entry])  | 
|
2272  | 
except KeyError:  | 
|
2273  | 
                        # No default
 | 
|
2274  | 
                        pass
 | 
|
2275  | 
||
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
2276  | 
ret_false = False  | 
2277  | 
out[entry] = True  | 
|
2278  | 
if self.stringify or missing:  | 
|
2279  | 
                    # if we are doing type conversion
 | 
|
2280  | 
                    # or the value is a supplied default
 | 
|
2281  | 
if not self.stringify:  | 
|
2282  | 
if isinstance(check, (list, tuple)):  | 
|
2283  | 
                            # preserve lists
 | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
2284  | 
check = [self._str(item) for item in check]  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
2285  | 
elif missing and check is None:  | 
2286  | 
                            # convert the None from a default to a ''
 | 
|
2287  | 
check = ''  | 
|
2288  | 
else:  | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
2289  | 
check = self._str(check)  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
2290  | 
if (check != val) or missing:  | 
2291  | 
section[entry] = check  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
2292  | 
if not copy and missing and entry not in section.defaults:  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
2293  | 
section.defaults.append(entry)  | 
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
2294  | 
        # Missing sections will have been created as empty ones when the
 | 
2295  | 
        # configspec was read.
 | 
|
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
2296  | 
for entry in section.sections:  | 
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
2297  | 
            # FIXME: this means DEFAULT is not copied in copy mode
 | 
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
2298  | 
if section is self and entry == 'DEFAULT':  | 
2299  | 
                continue
 | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
2300  | 
if copy:  | 
2301  | 
section.comments[entry] = section._cs_section_comments[entry]  | 
|
2302  | 
section.inline_comments[entry] = (  | 
|
2303  | 
section._cs_section_inline_comments[entry])  | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
2304  | 
check = self.validate(validator, preserve_errors=preserve_errors,  | 
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
2305  | 
copy=copy, section=section[entry])  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
2306  | 
out[entry] = check  | 
2307  | 
if check == False:  | 
|
2308  | 
ret_true = False  | 
|
2309  | 
elif check == True:  | 
|
2310  | 
ret_false = False  | 
|
2311  | 
else:  | 
|
2312  | 
ret_true = False  | 
|
2313  | 
ret_false = False  | 
|
2314  | 
        #
 | 
|
2315  | 
if ret_true:  | 
|
2316  | 
return True  | 
|
2317  | 
elif ret_false:  | 
|
2318  | 
return False  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
2319  | 
return out  | 
2320  | 
||
2321  | 
||
2322  | 
def reset(self):  | 
|
2323  | 
"""Clear ConfigObj instance and restore to 'freshly created' state."""  | 
|
2324  | 
self.clear()  | 
|
2325  | 
self._initialise()  | 
|
2326  | 
        # FIXME: Should be done by '_initialise', but ConfigObj constructor (and reload)
 | 
|
2327  | 
        #        requires an empty dictionary
 | 
|
2328  | 
self.configspec = None  | 
|
2329  | 
        # Just to be sure ;-)
 | 
|
2330  | 
self._original_configspec = None  | 
|
2331  | 
||
2332  | 
||
2333  | 
def reload(self):  | 
|
2334  | 
"""  | 
|
2335  | 
        Reload a ConfigObj from file.
 | 
|
2336  | 
        
 | 
|
2337  | 
        This method raises a ``ReloadError`` if the ConfigObj doesn't have
 | 
|
2338  | 
        a filename attribute pointing to a file.
 | 
|
2339  | 
        """
 | 
|
2340  | 
if not isinstance(self.filename, StringTypes):  | 
|
2341  | 
raise ReloadError()  | 
|
2342  | 
||
2343  | 
filename = self.filename  | 
|
2344  | 
current_options = {}  | 
|
2345  | 
for entry in OPTION_DEFAULTS:  | 
|
2346  | 
if entry == 'configspec':  | 
|
2347  | 
                continue
 | 
|
2348  | 
current_options[entry] = getattr(self, entry)  | 
|
2349  | 
||
2350  | 
configspec = self._original_configspec  | 
|
2351  | 
current_options['configspec'] = configspec  | 
|
2352  | 
||
2353  | 
self.clear()  | 
|
2354  | 
self._initialise(current_options)  | 
|
2355  | 
self._load(filename, configspec)  | 
|
2356  | 
||
2357  | 
||
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
2358  | 
|
2359  | 
class SimpleVal(object):  | 
|
2360  | 
"""  | 
|
2361  | 
    A simple validator.
 | 
|
2362  | 
    Can be used to check that all members expected are present.
 | 
|
2363  | 
    
 | 
|
2364  | 
    To use it, provide a configspec with all your members in (the value given
 | 
|
2365  | 
    will be ignored). Pass an instance of ``SimpleVal`` to the ``validate``
 | 
|
2366  | 
    method of your ``ConfigObj``. ``validate`` will return ``True`` if all
 | 
|
2367  | 
    members are present, or a dictionary with True/False meaning
 | 
|
2368  | 
    present/missing. (Whole missing sections will be replaced with ``False``)
 | 
|
2369  | 
    """
 | 
|
2370  | 
||
2371  | 
def __init__(self):  | 
|
2372  | 
self.baseErrorClass = ConfigObjError  | 
|
2373  | 
||
2374  | 
def check(self, check, member, missing=False):  | 
|
2375  | 
"""A dummy check method, always returns the value unchanged."""  | 
|
2376  | 
if missing:  | 
|
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
2377  | 
raise self.baseErrorClass()  | 
| 
1185.12.49
by Aaron Bentley
 Switched to ConfigObj  | 
2378  | 
return member  | 
2379  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
2380  | 
|
| 
1556.2.1
by Aaron Bentley
 Switched to ConfigObj 4.2.0  | 
2381  | 
# Check / processing functions for options
 | 
2382  | 
def flatten_errors(cfg, res, levels=None, results=None):  | 
|
2383  | 
"""  | 
|
2384  | 
    An example function that will turn a nested dictionary of results
 | 
|
2385  | 
    (as returned by ``ConfigObj.validate``) into a flat list.
 | 
|
2386  | 
    
 | 
|
2387  | 
    ``cfg`` is the ConfigObj instance being checked, ``res`` is the results
 | 
|
2388  | 
    dictionary returned by ``validate``.
 | 
|
2389  | 
    
 | 
|
2390  | 
    (This is a recursive function, so you shouldn't use the ``levels`` or
 | 
|
2391  | 
    ``results`` arguments - they are used by the function.
 | 
|
2392  | 
    
 | 
|
2393  | 
    Returns a list of keys that failed. Each member of the list is a tuple :
 | 
|
2394  | 
    ::
 | 
|
2395  | 
    
 | 
|
2396  | 
        ([list of sections...], key, result)
 | 
|
2397  | 
    
 | 
|
2398  | 
    If ``validate`` was called with ``preserve_errors=False`` (the default)
 | 
|
2399  | 
    then ``result`` will always be ``False``.
 | 
|
2400  | 
||
2401  | 
    *list of sections* is a flattened list of sections that the key was found
 | 
|
2402  | 
    in.
 | 
|
2403  | 
    
 | 
|
2404  | 
    If the section was missing then key will be ``None``.
 | 
|
2405  | 
    
 | 
|
2406  | 
    If the value (or section) was missing then ``result`` will be ``False``.
 | 
|
2407  | 
    
 | 
|
2408  | 
    If ``validate`` was called with ``preserve_errors=True`` and a value
 | 
|
2409  | 
    was present, but failed the check, then ``result`` will be the exception
 | 
|
2410  | 
    object returned. You can use this as a string that describes the failure.
 | 
|
2411  | 
    
 | 
|
2412  | 
    For example *The value "3" is of the wrong type*.
 | 
|
2413  | 
    
 | 
|
2414  | 
    >>> import validate
 | 
|
2415  | 
    >>> vtor = validate.Validator()
 | 
|
2416  | 
    >>> my_ini = '''
 | 
|
2417  | 
    ...     option1 = True
 | 
|
2418  | 
    ...     [section1]
 | 
|
2419  | 
    ...     option1 = True
 | 
|
2420  | 
    ...     [section2]
 | 
|
2421  | 
    ...     another_option = Probably
 | 
|
2422  | 
    ...     [section3]
 | 
|
2423  | 
    ...     another_option = True
 | 
|
2424  | 
    ...     [[section3b]]
 | 
|
2425  | 
    ...     value = 3
 | 
|
2426  | 
    ...     value2 = a
 | 
|
2427  | 
    ...     value3 = 11
 | 
|
2428  | 
    ...     '''
 | 
|
2429  | 
    >>> my_cfg = '''
 | 
|
2430  | 
    ...     option1 = boolean()
 | 
|
2431  | 
    ...     option2 = boolean()
 | 
|
2432  | 
    ...     option3 = boolean(default=Bad_value)
 | 
|
2433  | 
    ...     [section1]
 | 
|
2434  | 
    ...     option1 = boolean()
 | 
|
2435  | 
    ...     option2 = boolean()
 | 
|
2436  | 
    ...     option3 = boolean(default=Bad_value)
 | 
|
2437  | 
    ...     [section2]
 | 
|
2438  | 
    ...     another_option = boolean()
 | 
|
2439  | 
    ...     [section3]
 | 
|
2440  | 
    ...     another_option = boolean()
 | 
|
2441  | 
    ...     [[section3b]]
 | 
|
2442  | 
    ...     value = integer
 | 
|
2443  | 
    ...     value2 = integer
 | 
|
2444  | 
    ...     value3 = integer(0, 10)
 | 
|
2445  | 
    ...         [[[section3b-sub]]]
 | 
|
2446  | 
    ...         value = string
 | 
|
2447  | 
    ...     [section4]
 | 
|
2448  | 
    ...     another_option = boolean()
 | 
|
2449  | 
    ...     '''
 | 
|
2450  | 
    >>> cs = my_cfg.split('\\n')
 | 
|
2451  | 
    >>> ini = my_ini.split('\\n')
 | 
|
2452  | 
    >>> cfg = ConfigObj(ini, configspec=cs)
 | 
|
2453  | 
    >>> res = cfg.validate(vtor, preserve_errors=True)
 | 
|
2454  | 
    >>> errors = []
 | 
|
2455  | 
    >>> for entry in flatten_errors(cfg, res):
 | 
|
2456  | 
    ...     section_list, key, error = entry
 | 
|
2457  | 
    ...     section_list.insert(0, '[root]')
 | 
|
2458  | 
    ...     if key is not None:
 | 
|
2459  | 
    ...        section_list.append(key)
 | 
|
2460  | 
    ...     else:
 | 
|
2461  | 
    ...         section_list.append('[missing]')
 | 
|
2462  | 
    ...     section_string = ', '.join(section_list)
 | 
|
2463  | 
    ...     errors.append((section_string, ' = ', error))
 | 
|
2464  | 
    >>> errors.sort()
 | 
|
2465  | 
    >>> for entry in errors:
 | 
|
2466  | 
    ...     print entry[0], entry[1], (entry[2] or 0)
 | 
|
2467  | 
    [root], option2  =  0
 | 
|
2468  | 
    [root], option3  =  the value "Bad_value" is of the wrong type.
 | 
|
2469  | 
    [root], section1, option2  =  0
 | 
|
2470  | 
    [root], section1, option3  =  the value "Bad_value" is of the wrong type.
 | 
|
2471  | 
    [root], section2, another_option  =  the value "Probably" is of the wrong type.
 | 
|
2472  | 
    [root], section3, section3b, section3b-sub, [missing]  =  0
 | 
|
2473  | 
    [root], section3, section3b, value2  =  the value "a" is of the wrong type.
 | 
|
2474  | 
    [root], section3, section3b, value3  =  the value "11" is too big.
 | 
|
2475  | 
    [root], section4, [missing]  =  0
 | 
|
2476  | 
    """
 | 
|
2477  | 
if levels is None:  | 
|
2478  | 
        # first time called
 | 
|
2479  | 
levels = []  | 
|
2480  | 
results = []  | 
|
2481  | 
if res is True:  | 
|
2482  | 
return results  | 
|
2483  | 
if res is False:  | 
|
2484  | 
results.append((levels[:], None, False))  | 
|
2485  | 
if levels:  | 
|
2486  | 
levels.pop()  | 
|
2487  | 
return results  | 
|
2488  | 
for (key, val) in res.items():  | 
|
2489  | 
if val == True:  | 
|
2490  | 
            continue
 | 
|
2491  | 
if isinstance(cfg.get(key), dict):  | 
|
2492  | 
            # Go down one level
 | 
|
2493  | 
levels.append(key)  | 
|
2494  | 
flatten_errors(cfg[key], val, levels, results)  | 
|
2495  | 
            continue
 | 
|
2496  | 
results.append((levels[:], key, val))  | 
|
2497  | 
    #
 | 
|
2498  | 
    # Go up one level
 | 
|
2499  | 
if levels:  | 
|
2500  | 
levels.pop()  | 
|
2501  | 
    #
 | 
|
2502  | 
return results  | 
|
2503  | 
||
| 
3221.7.1
by Matt Nordhoff
 Upgrade ConfigObj to version 4.5.1.  | 
2504  | 
|
| 
2991.2.1
by Vincent Ladeuil
 Update configobj to version 4.4.0:  | 
2505  | 
"""*A programming language is a medium of expression.* - Paul Graham"""
 |