Merge lp:~ricardokirkner/configglue/multi-file-interpolation into lp:configglue

Proposed by Ricardo Kirkner
Status: Merged
Approved by: Ricardo Kirkner
Approved revision: 112
Merged at revision: 110
Proposed branch: lp:~ricardokirkner/configglue/multi-file-interpolation
Merge into: lp:configglue
Diff against target: 240 lines (+126/-30)
2 files modified
configglue/parser.py (+9/-1)
configglue/tests/test_parser.py (+117/-29)
To merge this branch: bzr merge lp:~ricardokirkner/configglue/multi-file-interpolation
Reviewer Review Type Date Requested Status
Ricardo Kirkner Approve
Natalia Bidart Approve
Review via email: mp+174740@code.launchpad.net

Commit message

allow interpolating with __noschema__ values across included files

To post a comment you must log in.
Revision history for this message
Natalia Bidart (nataliabidart) wrote :

Looks good!

review: Approve
Revision history for this message
Ubuntu One Auto Pilot (otto-pilot) wrote :

Voting does not meet specified criteria. Required: Approve >= 1, Disapprove == 0, Needs Fixing == 0, Needs Information == 0, Resubmit == 0, Pending == 0. Got: 1 Pending.

Revision history for this message
Ricardo Kirkner (ricardokirkner) wrote :

Rubber stamping

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'configglue/parser.py'
--- configglue/parser.py 2013-07-11 17:01:58 +0000
+++ configglue/parser.py 2013-07-15 18:06:23 +0000
@@ -282,7 +282,15 @@
282 fpname)282 fpname)
283 includes = self.get('__main__', 'includes')283 includes = self.get('__main__', 'includes')
284 filenames = [text_type.strip(x) for x in includes]284 filenames = [text_type.strip(x) for x in includes]
285 self.read(filenames, already_read=already_read)285
286 # parse included files
287 sub_parser = self.__class__(self.schema)
288 sub_parser._basedir = self._basedir
289 sub_parser._location = self._location
290 sub_parser.read(filenames)
291 # update current parser with those values
292 self._sections.update(sub_parser._sections)
293
286 self._basedir = old_basedir294 self._basedir = old_basedir
287295
288 if filenames:296 if filenames:
289297
=== modified file 'configglue/tests/test_parser.py'
--- configglue/tests/test_parser.py 2013-07-11 17:01:58 +0000
+++ configglue/tests/test_parser.py 2013-07-15 18:06:23 +0000
@@ -109,6 +109,7 @@
109 """Test parser include files using relative paths."""109 """Test parser include files using relative paths."""
110 def setup_config():110 def setup_config():
111 folder = tempfile.mkdtemp()111 folder = tempfile.mkdtemp()
112 self.addCleanup(shutil.rmtree, folder)
112113
113 f = codecs.open("%s/first.cfg" % folder, 'w',114 f = codecs.open("%s/first.cfg" % folder, 'w',
114 encoding=CONFIG_FILE_ENCODING)115 encoding=CONFIG_FILE_ENCODING)
@@ -150,16 +151,11 @@
150 # make sure we leave the basedir clean151 # make sure we leave the basedir clean
151 self.assertEqual(parser._basedir, '')152 self.assertEqual(parser._basedir, '')
152153
153 # silently remove any created files
154 try:
155 shutil.rmtree(folder)
156 except:
157 pass
158
159 def test_local_override(self):154 def test_local_override(self):
160 """Test parser override values from included files."""155 """Test parser override values from included files."""
161 def setup_config():156 def setup_config():
162 folder = tempfile.mkdtemp()157 folder = tempfile.mkdtemp()
158 self.addCleanup(shutil.rmtree, folder)
163159
164 f = codecs.open("%s/first.cfg" % folder, 'w',160 f = codecs.open("%s/first.cfg" % folder, 'w',
165 encoding=CONFIG_FILE_ENCODING)161 encoding=CONFIG_FILE_ENCODING)
@@ -190,11 +186,51 @@
190 # make sure we leave the basedir clean186 # make sure we leave the basedir clean
191 self.assertEqual(parser._basedir, '')187 self.assertEqual(parser._basedir, '')
192188
193 # silently remove any created files189 def test_multiple_includes(self):
194 try:190 """Test parser correctly handles multiple included files."""
195 shutil.rmtree(folder)191 def setup_config():
196 except:192 folder = tempfile.mkdtemp()
197 pass193 self.addCleanup(shutil.rmtree, folder)
194
195 f = codecs.open("%s/first.cfg" % folder, 'w',
196 encoding=CONFIG_FILE_ENCODING)
197 f.write("[__main__]\nfoo=1\nbar=1")
198 f.close()
199
200 f = codecs.open("%s/second.cfg" % folder, 'w',
201 encoding=CONFIG_FILE_ENCODING)
202 f.write("[__main__]\nfoo=2\nbar=2")
203 f.close()
204
205 f = codecs.open("%s/third.cfg" % folder, 'w',
206 encoding=CONFIG_FILE_ENCODING)
207 f.write("[__main__]\nfoo=3\nbar=3")
208 f.close()
209
210 config = textwrap.dedent("""
211 [__main__]
212 includes =
213 {folder}/first.cfg
214 {folder}/second.cfg
215 {folder}/third.cfg
216 foo = 4
217 """.format(folder=folder))
218 config = BytesIO(config.encode(CONFIG_FILE_ENCODING))
219 return config, folder
220
221 class MySchema(Schema):
222 foo = IntOption()
223 bar = IntOption()
224
225 config, folder = setup_config()
226 expected_values = {'__main__': {'foo': 4, 'bar': 3}}
227 parser = SchemaConfigParser(MySchema())
228 # make sure we start on a clean basedir
229 self.assertEqual(parser._basedir, '')
230 parser.readfp(config, 'my.cfg')
231 self.assertEqual(parser.values(), expected_values)
232 # make sure we leave the basedir clean
233 self.assertEqual(parser._basedir, '')
198234
199235
200class TestInterpolation(unittest.TestCase):236class TestInterpolation(unittest.TestCase):
@@ -266,6 +302,73 @@
266 self.assertRaises(InterpolationMissingOptionError,302 self.assertRaises(InterpolationMissingOptionError,
267 parser.get, 'foo', 'bar')303 parser.get, 'foo', 'bar')
268304
305 def test_interpolate_across_includes(self):
306 """Test interpolation across included files."""
307 def setup_config():
308 folder = tempfile.mkdtemp()
309 self.addCleanup(shutil.rmtree, folder)
310
311 f = codecs.open("%s/first.cfg" % folder, 'w',
312 encoding=CONFIG_FILE_ENCODING)
313 f.write("[__main__]\nfoo=1\nincludes=second.cfg")
314 f.close()
315
316 f = codecs.open("%s/second.cfg" % folder, 'w',
317 encoding=CONFIG_FILE_ENCODING)
318 f.write("[__main__]\nbar=3")
319 f.close()
320
321 config = "[__main__]\nfoo=%%(bar)s\nincludes=%s/first.cfg" % folder
322 config = BytesIO(config.encode(CONFIG_FILE_ENCODING))
323 return config, folder
324
325 class MySchema(Schema):
326 foo = IntOption()
327 bar = IntOption()
328
329 config, folder = setup_config()
330 expected_values = {'__main__': {'foo': 3, 'bar': 3}}
331 parser = SchemaConfigParser(MySchema())
332 # make sure we start on a clean basedir
333 self.assertEqual(parser._basedir, '')
334 parser.readfp(config, 'my.cfg')
335 self.assertEqual(parser.values(), expected_values)
336 # make sure we leave the basedir clean
337 self.assertEqual(parser._basedir, '')
338
339 def test_interpolate_using_noschema(self):
340 """Test interpolation across included files."""
341 def setup_config():
342 folder = tempfile.mkdtemp()
343 self.addCleanup(shutil.rmtree, folder)
344
345 f = codecs.open("%s/first.cfg" % folder, 'w',
346 encoding=CONFIG_FILE_ENCODING)
347 f.write("[__noschema__]\nbar=1\n[__main__]\nincludes=second.cfg")
348 f.close()
349
350 f = codecs.open("%s/second.cfg" % folder, 'w',
351 encoding=CONFIG_FILE_ENCODING)
352 f.write("[__noschema__]\nbar=3")
353 f.close()
354
355 config = "[__main__]\nfoo=%%(bar)s\nincludes=%s/first.cfg" % folder
356 config = BytesIO(config.encode(CONFIG_FILE_ENCODING))
357 return config, folder
358
359 class MySchema(Schema):
360 foo = IntOption()
361
362 config, folder = setup_config()
363 expected_values = {'__main__': {'foo': 1}}
364 parser = SchemaConfigParser(MySchema())
365 # make sure we start on a clean basedir
366 self.assertEqual(parser._basedir, '')
367 parser.readfp(config, 'my.cfg')
368 self.assertEqual(parser.values(), expected_values)
369 # make sure we leave the basedir clean
370 self.assertEqual(parser._basedir, '')
371
269 def test_interpolate_invalid_key(self):372 def test_interpolate_invalid_key(self):
270 """Test interpolation of invalid key."""373 """Test interpolation of invalid key."""
271 class MySchema(Schema):374 class MySchema(Schema):
@@ -882,6 +985,7 @@
882 def test_read_multiple_files(self):985 def test_read_multiple_files(self):
883 def setup_config():986 def setup_config():
884 folder = tempfile.mkdtemp()987 folder = tempfile.mkdtemp()
988 self.addCleanup(shutil.rmtree, folder)
885989
886 f = codecs.open("%s/first.cfg" % folder, 'w',990 f = codecs.open("%s/first.cfg" % folder, 'w',
887 encoding=CONFIG_FILE_ENCODING)991 encoding=CONFIG_FILE_ENCODING)
@@ -900,12 +1004,6 @@
900 self.parser.read(files)1004 self.parser.read(files)
901 self.assertEqual(self.parser.values(), {'__main__': {'foo': 'bar'}})1005 self.assertEqual(self.parser.values(), {'__main__': {'foo': 'bar'}})
9021006
903 # silently remove any created files
904 try:
905 shutil.rmtree(folder)
906 except:
907 pass
908
909 def test_read_utf8_encoded_file(self):1007 def test_read_utf8_encoded_file(self):
910 # create config file1008 # create config file
911 fp, filename = tempfile.mkstemp()1009 fp, filename = tempfile.mkstemp()
@@ -1053,6 +1151,7 @@
1053 """Test parser save config values to original files."""1151 """Test parser save config values to original files."""
1054 def setup_config():1152 def setup_config():
1055 folder = tempfile.mkdtemp()1153 folder = tempfile.mkdtemp()
1154 self.addCleanup(shutil.rmtree, folder)
10561155
1057 f = codecs.open("%s/first.cfg" % folder, 'w',1156 f = codecs.open("%s/first.cfg" % folder, 'w',
1058 encoding=CONFIG_FILE_ENCODING)1157 encoding=CONFIG_FILE_ENCODING)
@@ -1095,15 +1194,10 @@
1095 # new value goes into last read config file1194 # new value goes into last read config file
1096 self.assertTrue('baz = 42' in data)1195 self.assertTrue('baz = 42' in data)
10971196
1098 # silently remove any created files
1099 try:
1100 shutil.rmtree(folder)
1101 except:
1102 pass
1103
1104 def test_save_config_last_location_nested_includes(self):1197 def test_save_config_last_location_nested_includes(self):
1105 def setup_config():1198 def setup_config():
1106 folder = tempfile.mkdtemp()1199 folder = tempfile.mkdtemp()
1200 self.addCleanup(shutil.rmtree, folder)
11071201
1108 f = codecs.open("%s/first.cfg" % folder, 'w',1202 f = codecs.open("%s/first.cfg" % folder, 'w',
1109 encoding=CONFIG_FILE_ENCODING)1203 encoding=CONFIG_FILE_ENCODING)
@@ -1151,12 +1245,6 @@
1151 # not in the last included config file1245 # not in the last included config file
1152 self.assertTrue('baz = 42' in data)1246 self.assertTrue('baz = 42' in data)
11531247
1154 # silently remove any created files
1155 try:
1156 shutil.rmtree(folder)
1157 except:
1158 pass
1159
11601248
1161class TestParserIsValid(unittest.TestCase):1249class TestParserIsValid(unittest.TestCase):
1162 def setUp(self):1250 def setUp(self):

Subscribers

People subscribed via source and target branches