configglue team mailing list archive
-
configglue team
-
Mailing list archive
-
Message #00494
[Merge] lp:~ricardokirkner/configglue/multi-file-interpolation into lp:configglue
Ricardo Kirkner has proposed merging lp:~ricardokirkner/configglue/multi-file-interpolation into lp:configglue.
Commit message:
allow interpolating with __noschema__ values across included files
Requested reviews:
Configglue developers (configglue)
Related bugs:
Bug #1076679 in configglue: "included files override in wrong order"
https://bugs.launchpad.net/configglue/+bug/1076679
For more details, see:
https://code.launchpad.net/~ricardokirkner/configglue/multi-file-interpolation/+merge/174740
--
https://code.launchpad.net/~ricardokirkner/configglue/multi-file-interpolation/+merge/174740
Your team Configglue developers is requested to review the proposed merge of lp:~ricardokirkner/configglue/multi-file-interpolation into lp:configglue.
=== modified file 'configglue/parser.py'
--- configglue/parser.py 2013-07-11 17:01:58 +0000
+++ configglue/parser.py 2013-07-15 12:29:24 +0000
@@ -282,7 +282,15 @@
fpname)
includes = self.get('__main__', 'includes')
filenames = [text_type.strip(x) for x in includes]
- self.read(filenames, already_read=already_read)
+
+ # parse included files
+ sub_parser = self.__class__(self.schema)
+ sub_parser._basedir = self._basedir
+ sub_parser._location = self._location
+ sub_parser.read(filenames)
+ # update current parser with those values
+ self._sections.update(sub_parser._sections)
+
self._basedir = old_basedir
if filenames:
=== 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 12:29:24 +0000
@@ -196,6 +196,57 @@
except:
pass
+ def test_multiple_includes(self):
+ """Test parser correctly handles multiple included files."""
+ def setup_config():
+ folder = tempfile.mkdtemp()
+
+ f = codecs.open("%s/first.cfg" % folder, 'w',
+ encoding=CONFIG_FILE_ENCODING)
+ f.write("[__main__]\nfoo=1\nbar=1")
+ f.close()
+
+ f = codecs.open("%s/second.cfg" % folder, 'w',
+ encoding=CONFIG_FILE_ENCODING)
+ f.write("[__main__]\nfoo=2\nbar=2")
+ f.close()
+
+ f = codecs.open("%s/third.cfg" % folder, 'w',
+ encoding=CONFIG_FILE_ENCODING)
+ f.write("[__main__]\nfoo=3\nbar=3")
+ f.close()
+
+ config = textwrap.dedent("""
+ [__main__]
+ includes =
+ {folder}/first.cfg
+ {folder}/second.cfg
+ {folder}/third.cfg
+ foo = 4
+ """.format(folder=folder))
+ config = BytesIO(config.encode(CONFIG_FILE_ENCODING))
+ return config, folder
+
+ class MySchema(Schema):
+ foo = IntOption()
+ bar = IntOption()
+
+ config, folder = setup_config()
+ expected_values = {'__main__': {'foo': 4, 'bar': 3}}
+ parser = SchemaConfigParser(MySchema())
+ # make sure we start on a clean basedir
+ self.assertEqual(parser._basedir, '')
+ parser.readfp(config, 'my.cfg')
+ self.assertEqual(parser.values(), expected_values)
+ # make sure we leave the basedir clean
+ self.assertEqual(parser._basedir, '')
+
+ # silently remove any created files
+ try:
+ shutil.rmtree(folder)
+ except:
+ pass
+
class TestInterpolation(unittest.TestCase):
"""Test basic interpolation."""
@@ -266,6 +317,83 @@
self.assertRaises(InterpolationMissingOptionError,
parser.get, 'foo', 'bar')
+ def test_interpolate_across_includes(self):
+ """Test interpolation across included files."""
+ def setup_config():
+ folder = tempfile.mkdtemp()
+
+ f = codecs.open("%s/first.cfg" % folder, 'w',
+ encoding=CONFIG_FILE_ENCODING)
+ f.write("[__main__]\nfoo=1\nincludes=second.cfg")
+ f.close()
+
+ f = codecs.open("%s/second.cfg" % folder, 'w',
+ encoding=CONFIG_FILE_ENCODING)
+ f.write("[__main__]\nbar=3")
+ f.close()
+
+ config = "[__main__]\nfoo=%%(bar)s\nincludes=%s/first.cfg" % folder
+ config = BytesIO(config.encode(CONFIG_FILE_ENCODING))
+ return config, folder
+
+ class MySchema(Schema):
+ foo = IntOption()
+ bar = IntOption()
+
+ config, folder = setup_config()
+ expected_values = {'__main__': {'foo': 3, 'bar': 3}}
+ parser = SchemaConfigParser(MySchema())
+ # make sure we start on a clean basedir
+ self.assertEqual(parser._basedir, '')
+ parser.readfp(config, 'my.cfg')
+ self.assertEqual(parser.values(), expected_values)
+ # make sure we leave the basedir clean
+ self.assertEqual(parser._basedir, '')
+
+ # silently remove any created files
+ try:
+ shutil.rmtree(folder)
+ except:
+ pass
+
+ def test_interpolate_using_noschema(self):
+ """Test interpolation across included files."""
+ def setup_config():
+ folder = tempfile.mkdtemp()
+
+ f = codecs.open("%s/first.cfg" % folder, 'w',
+ encoding=CONFIG_FILE_ENCODING)
+ f.write("[__noschema__]\nbar=1\n[__main__]\nincludes=second.cfg")
+ f.close()
+
+ f = codecs.open("%s/second.cfg" % folder, 'w',
+ encoding=CONFIG_FILE_ENCODING)
+ f.write("[__noschema__]\nbar=3")
+ f.close()
+
+ config = "[__main__]\nfoo=%%(bar)s\nincludes=%s/first.cfg" % folder
+ config = BytesIO(config.encode(CONFIG_FILE_ENCODING))
+ return config, folder
+
+ class MySchema(Schema):
+ foo = IntOption()
+
+ config, folder = setup_config()
+ expected_values = {'__main__': {'foo': 1}}
+ parser = SchemaConfigParser(MySchema())
+ # make sure we start on a clean basedir
+ self.assertEqual(parser._basedir, '')
+ parser.readfp(config, 'my.cfg')
+ self.assertEqual(parser.values(), expected_values)
+ # make sure we leave the basedir clean
+ self.assertEqual(parser._basedir, '')
+
+ # silently remove any created files
+ try:
+ shutil.rmtree(folder)
+ except:
+ pass
+
def test_interpolate_invalid_key(self):
"""Test interpolation of invalid key."""
class MySchema(Schema):
Follow ups