19
19
import io
20
20
import re
21
21
import logging
22
- from collections import MutableMapping
23
22
try :
24
23
from collections import OrderedDict
25
24
except ImportError :
@@ -67,7 +66,7 @@ def keys(self):
67
66
iteritems = DictMixin .iteritems
68
67
69
68
70
- __version__ = "0.5.1 "
69
+ __version__ = "0.7.0 "
71
70
__project__ = "Inirama"
72
71
__author__ = "Kirill Klenov <horneds@gmail.com>"
73
72
__license__ = "BSD"
@@ -170,7 +169,9 @@ class INIScanner(Scanner):
170
169
('SECTION' , re .compile (r'\[[^]]+\]' )),
171
170
('IGNORE' , re .compile (r'[ \r\t\n]+' )),
172
171
('COMMENT' , re .compile (r'[;#].*' )),
173
- ('KEY' , re .compile (r'[\w_]+\s*[:=].*' ))]
172
+ ('KEY' , re .compile (r'[\w_]+\s*[:=].*' )),
173
+ ('CONTINUATION' , re .compile (r'.*' ))
174
+ ]
174
175
175
176
ignore = ['IGNORE' ]
176
177
@@ -183,43 +184,20 @@ def pre_scan(self):
183
184
undefined = object ()
184
185
185
186
186
- class Section (MutableMapping ):
187
+ class Section (OrderedDict ):
187
188
188
189
""" Representation of INI section. """
189
190
190
191
def __init__ (self , namespace , * args , ** kwargs ):
191
192
super (Section , self ).__init__ (* args , ** kwargs )
192
193
self .namespace = namespace
193
- self .__storage__ = dict ()
194
194
195
195
def __setitem__ (self , name , value ):
196
196
value = str (value )
197
197
if value .isdigit ():
198
198
value = int (value )
199
199
200
- self .__storage__ [name ] = value
201
-
202
- def __getitem__ (self , name ):
203
- return self .__storage__ [name ]
204
-
205
- def __delitem__ (self , name ):
206
- del self .__storage__ [name ]
207
-
208
- def __len__ (self ):
209
- return len (self .__storage__ )
210
-
211
- def __iter__ (self ):
212
- return iter (self .__storage__ )
213
-
214
- def __repr__ (self ):
215
- return "<{0} {1}>" .format (self .__class__ .__name__ , str (dict (self )))
216
-
217
- def iteritems (self ):
218
- """ Impletment iteritems. """
219
- for key in self .__storage__ .keys ():
220
- yield key , self [key ]
221
-
222
- items = lambda s : list (s .iteritems ())
200
+ super (Section , self ).__setitem__ (name , value )
223
201
224
202
225
203
class InterpolationSection (Section ):
@@ -246,19 +224,28 @@ def __interpolate__(self, math):
246
224
except KeyError :
247
225
return ''
248
226
249
- def __getitem__ (self , name ):
227
+ def __getitem__ (self , name , raw = False ):
250
228
value = super (InterpolationSection , self ).__getitem__ (name )
251
- sample = undefined
252
- while sample != value :
253
- try :
254
- sample , value = value , self .var_re .sub (
255
- self .__interpolate__ , value )
256
- except RuntimeError :
257
- message = "Interpolation failed: {0}" .format (name )
258
- NS_LOGGER .error (message )
259
- raise ValueError (message )
229
+ if not raw :
230
+ sample = undefined
231
+ while sample != value :
232
+ try :
233
+ sample , value = value , self .var_re .sub (
234
+ self .__interpolate__ , value )
235
+ except RuntimeError :
236
+ message = "Interpolation failed: {0}" .format (name )
237
+ NS_LOGGER .error (message )
238
+ raise ValueError (message )
260
239
return value
261
240
241
+ def iteritems (self , raw = False ):
242
+ """ Iterate self items. """
243
+
244
+ for key in self :
245
+ yield key , self .__getitem__ (key , raw = raw )
246
+
247
+ items = iteritems
248
+
262
249
263
250
class Namespace (object ):
264
251
@@ -356,6 +343,7 @@ def parse(self, source, update=True, **params):
356
343
scanner .scan ()
357
344
358
345
section = self .default_section
346
+ name = None
359
347
360
348
for token in scanner .tokens :
361
349
if token [0 ] == 'KEY' :
@@ -368,6 +356,13 @@ def parse(self, source, update=True, **params):
368
356
elif token [0 ] == 'SECTION' :
369
357
section = token [1 ].strip ('[]' )
370
358
359
+ elif token [0 ] == 'CONTINUATION' :
360
+ if not name :
361
+ raise SyntaxError (
362
+ "SyntaxError[@char {0}: {1}]" .format (
363
+ token [2 ], "Bad continuation." ))
364
+ self [section ][name ] += '\n ' + token [1 ].strip ()
365
+
371
366
def __getitem__ (self , name ):
372
367
""" Look name in self sections.
373
368
@@ -406,4 +401,4 @@ class InterpolationNamespace(Namespace):
406
401
407
402
section_type = InterpolationSection
408
403
409
- # lint_ignore=W0201,R0924,F0401
404
+ # pylama:ignore=D,W02,E731,W0621
0 commit comments