From d0add2889335d69d4bb17e8fd962e53dcee207bc Mon Sep 17 00:00:00 2001 From: Tomas Gavenciak Date: Wed, 22 Sep 2010 23:59:52 +0200 Subject: [PATCH] Add context manager to ConfigTree.parse Now we can do: with parse("..."): use modified config raise exception Also adapted one test. Yay! --- t/moe/config.py | 34 +++++++++++++++++++++++++++------- t/moe/config_test.py | 23 +++++++++++++++-------- 2 files changed, 42 insertions(+), 15 deletions(-) diff --git a/t/moe/config.py b/t/moe/config.py index 04e363f..abc8269 100644 --- a/t/moe/config.py +++ b/t/moe/config.py @@ -55,6 +55,17 @@ class VariableFixedError(ConfigError): class CyclicConfigError(ConfigError): pass +class ParseProxy(list): + """Proxy helper class around values returned by `parse` and `parse_file`, + useful in "with" constructs.""" + def __init__(self, config, parsed_ops): + super(ParseProxy, self).__init__(parsed_ops) + self.config = config + def __enter__(self): + pass + def __exit__(self, etype, value, traceback): + self.config.remove(list(self)) + class ConfigTree(object): """ @@ -110,20 +121,29 @@ class ConfigTree(object): v = self.lookup(vname, create = True) v.remove_operation(o) - def parse(self, s, source=None, level=0): - """Parse `s` (stream/string) into the tree, see `moe.confparser.ConfigParser` for details. - Returns list of parset operations: [(varname, `Operation`)]""" + def parse(self, s, source=None, level=0, proxy=True): + """Parse `s` (stream/string) into the tree, see `moe.config_parser.ConfigParser` for details. + Returns list of parset operations: [(varname, `Operation`)]. + By default returns a proxy list-like object that can be used in "with" constructs: + + with config.parse("TEST='1'"): + print config['TEST'] + raise StupidError + """ import moe.config_parser p = moe.config_parser.ConfigParser(s, self, source=source, level=level) - return p.parse() + l = p.parse() + if not proxy: + return l + return ParseProxy(self, l) - def parse_file(self, filename, desc=None, level=0): - """Parse an utf-8 file into the tree, see `moe.confparser.ConfigParser` for details. + def parse_file(self, filename, desc=None, level=0, proxy=True): + """Parse an utf-8 file into the tree using func:`parse`. Names the source "`filename` <`desc`>". """ with open(filename, 'rt') as f: if desc: filename += " <" + desc + ">" - return self.parse(f, source=filename, level=level) + return self.parse(f, source=filename, level=level, proxy=proxy) class ConfigElem(object): diff --git a/t/moe/config_test.py b/t/moe/config_test.py index 2a0325b..f1c836d 100644 --- a/t/moe/config_test.py +++ b/t/moe/config_test.py @@ -12,11 +12,7 @@ class TestConfig(unittest.TestCase): s.t = cf.ConfigTree() def parse(s, string, level=0, fname='test'): - cp = ConfigParser(string, s.t, fname, level) - ops = cp.parse() - cp.p_WS() - assert cp.eof() - return ops + return s.t.parse(string, source=fname, level=level) def var(s, varname, create=True): return s.t.lookup(varname, create=create) @@ -83,21 +79,32 @@ class TestParser(TestConfig): s.assertRaises(ConfigSyntaxError, s.parse, "if 'a'<>'b' {}") def test_parse_remove(s): - s.parse('a="000"') + def raise_UserWarning(): + with s.parse("b='F'", level=99): + assert s.val('b') == 'F' + raise UserWarning + d0 = s.parse('a="000"') d1 = s.parse("a='A'; b='B'; c='C'", level=10) d2 = s.parse('c="{a}{a}"; b="XX" ', level=20) d3 = s.parse('b+=c ', level=30) assert s.val('b') == "XXAA" s.t.remove(d2) assert s.val('b') == "BC" - s.assertRaises(ValueError, s.t.remove, [('d', d1[1][0])]) - s.assertRaises(ValueError, s.t.remove, [('b', d1[1][0])]) + s.assertRaises(ValueError, s.t.remove, [('d', d1[0][1])]) + s.assertRaises(ValueError, s.t.remove, [('b', d1[0][1])]) + # Try exception in "with parse():" + s.assertRaises(UserWarning, raise_UserWarning) + assert s.val('b') == "BC" # partially remove d1 s.t.remove([('c', d1[2][1])]) # try to remove rest - 'a' and 'b' should get removed s.assertRaises(ValueError, s.t.remove, d1) assert s.val('a') == "000" + # cleanup s.t.remove(d3) + s.t.remove(d0) + for v in 'abcd': + assert len(s.var(v).operations) == 0 class TestConfigEval(TestConfig): -- 2.39.2