"""
-config.py
--------
-
Lazy conditional string evaluation module for Moe configuration variables.
-
* Each variable has ordered list of operations (definitions), each defining operation either
-assigns (SET) or appends (APPEND) value of an expression to the variable. Each operation may be guarded by condition(s).
-
-NOTE: If no 'SET' applies, a variable is still undefined even if some 'APPEND' applies. This might change.
+ assigns (SET) or appends (APPEND) value of an expression to the variable. Each operation may be guarded by condition(s).
* Each condition is a formula (tree consisting of 'AND', 'OR', 'NOT' and '==', '!=' between two expressions.
* Expression is a list of strings and variables to be expanded.
-NOTE: All expanded data should be (or is converted to) unicode
-
-
-TODO (OPT): Cleanup of unused undefined variables.
-TODO (OPT): Better variable name checking (no name '.'-structural prefix of another)
-TODO (OPT): Implemet "subtree" listing.
+.. note:: If no 'SET' applies, a variable is still undefined even if some 'APPEND' applies. This might change.
+.. note:: All expanded data should be (or is converted to) unicode
+.. todo:: (OPT) Cleanup of unused undefined variables.
+.. todo:: (OPT) Better variable name checking (no name '.'-structural prefix of another)
+.. todo:: (OPT) Implemet "subtree" listing.
"""
import types, itertools, re, bisect
self.variables[k].dump(prefix) for k in sorted(self.variables.keys())
])
+ def fix(self, keys):
+ "Fix value of variable or list of variables. Fixing undefined variable raises `UndefinedError`."
+ if isinstance(keys, types.StringTypes):
+ keys = [keys]
+ for key in keys:
+ self.lookup(key, create=True).fix()
+
def parse(self, s, source=None, level=0):
"""Parse `s` (stream/string) into the tree, see `moe.confparser.ConfigParser` for details."""
- import moe.confparser
- p = moe.confparser.ConfigParser(text, self, source=source, level=level)
+ import moe.config_parser
+ p = moe.config_parser.ConfigParser(s, self, source=source, level=level)
p.parse()
def parse_file(self, filename, desc=None, level=0):
"""Parse an utf-8 file into the tree, see `moe.confparser.ConfigParser` for details.
Names the source "`filename` <`desc`>". """
- f = open(filename, 'rt')
- if desc:
- filename += " <" + desc + ">"
- self.parse(f, source=filename, level=level)
+ with open(filename, 'rt') as f:
+ if desc:
+ filename += " <" + desc + ">"
+ self.parse(f, source=filename, level=level)
class ConfigElem(object):
class ConfigCondition(ConfigElem):
"""
Condition using equality and logic operators.
- Clause is a tuple-tree in the following recursive form:
- ('AND', c1, c1), ('OR', c1, c2), ('NOT', c1),
- ('==', e1, e2), ('!=', e1, e2) where e1, e2 are `ConfigExpression`s.
+ Clause is a tuple-tree in the following recursive form::
+
+ ('AND', c1, c1), ('OR', c1, c2), ('NOT', c1), ('==', e1, e2), ('!=', e1, e2)
+
+ where e1, e2 are `ConfigExpression`, c1, c2, `ConfigCondition`.
"""
def __init__(self, formula, text=None, parent=None):
self.fixed = True
def unfix(self):
- "Set the variable to be modifiable again."
+ "Make the variable modifiable again."
self.fixed = False
def value(self, depth=0):
"Handle the case when fixed, raise exc. on different evaluation"
val = super(ConfigVar,self).value(depth)
if self.fixed and self.fixed_val != val:
- raise VariableFixedError("value of var %s was fixed to %r but evaluated to %r", self.name, self.fixed_val, val)
+ raise VariableFixedError("value of var %r was fixed to %r but evaluated to %r", self.name, self.fixed_val, val)
return val
def add_operation(self, operation):