Skip to content

Commit

Permalink
Additional updates to ConfigBase.__call__ internals, and adding tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jsiirola committed Dec 13, 2018
1 parent 8a5fb3c commit 5dfe8ad
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 30 deletions.
80 changes: 56 additions & 24 deletions pyutilib/misc/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def dump(x, **args):

__all__ = ('ConfigBlock', 'ConfigList', 'ConfigValue')

logger = logging.getLogger('pyutilib.misc')
logger = logging.getLogger('pyutilib.misc.config')


def _munge_name(name, space_to_dash=True):
Expand Down Expand Up @@ -171,29 +171,57 @@ def __setstate__(self, state):
# of setting self.__dict__[key] = val.
object.__setattr__(self, key, val)

def __call__(self, value=NoArgument, domain=NoArgument,
description=NoArgument, doc=NoArgument, visibility=NoArgument):
ans = self.__class__()
ans._default = self.value()
if domain is NoArgument:
ans._domain = self._domain
def __call__(self, value=NoArgument, default=NoArgument, domain=NoArgument,
description=NoArgument, doc=NoArgument, visibility=NoArgument,
implicit=NoArgument, implicit_domain=NoArgument):
# We will pass through overriding arguments to the constructor.
# This way if the constructor does special processing of any of
# the arguments (like implicit_domain), we don't have to repeat
# that code here. Unfortunately, it means we need to do a bit
# of logic to be sure we only pass through appropriate
# arguments.
kwds = {}
kwds['description'] = ( self._description
if description is ConfigBase.NoArgument else
description )
kwds['doc'] = ( self._doc
if doc is ConfigBase.NoArgument else
doc )
kwds['visibility'] = ( self._visibility
if visibility is ConfigBase.NoArgument else
visibility )
if isinstance(self, ConfigBlock):
kwds['implicit'] = ( self._implicit_declaration
if implicit is ConfigBase.NoArgument else
implicit )
kwds['implicit_domain'] = (
self._implicit_domain
if implicit_domain is ConfigBase.NoArgument else
implicit_domain )
if domain is not ConfigBase.NoArgument:
logger.warn("domain ignored by __call__(): "
"class is a ConfigBlock" % (type(self),))
if default is not ConfigBase.NoArgument:
logger.warn("default ignored by __call__(): "
"class is a ConfigBlock" % (type(self),))
else:
ans._domain = domain
if description is NoArgument:
ans._description = self._description
else:
ans._description = _strip_indentation(description)
if doc is NoArgument:
ans._doc = self._doc
else:
ans._doc = _strip_indentation(doc)
if visibility is NoArgument:
ans._visibility = self._visibility
else:
ans._visibility = visibility
if self.__class__ is ConfigBlock:
ans._implicit_declaration = self._implicit_declaration
ans._implicit_domain = self._implicit_domain
kwds['default'] = ( self.value()
if default is ConfigBase.NoArgument else
default )
kwds['domain'] = ( self._domain
if domain is ConfigBase.NoArgument else
domain )
if implicit is not ConfigBase.NoArgument:
logger.warn("implicit ignored by __call__(): "
"class %s is not a ConfigBlock" % (type(self),))
if implicit_domain is not ConfigBase.NoArgument:
logger.warn("implicit_domain ignored by __call__(): "
"class %s is not a ConfigBlock" % (type(self),))

# Copy over any other object-specific information (mostly Block
# definitions)
ans = self.__class__(**kwds)
if isinstance(self, ConfigBlock):
for k in self._decl_order:
if k in self._declared:
v = self._data[k]
Expand All @@ -204,6 +232,7 @@ def __call__(self, value=NoArgument, domain=NoArgument,
_tmp._name = v._name
else:
ans.reset()
# ... and set the value, if appropriate
if value is not ConfigBase.NoArgument:
ans.set_value(value)
return ans
Expand Down Expand Up @@ -234,7 +263,10 @@ def _cast(self, value):
return value
if self._domain is not None:
try:
return self._domain(value)
if value is not ConfigBase.NoArgument:
return self._domain(value)
else:
return self._domain()
except:
err = exc_info()[1]
if hasattr(self._domain, '__name__'):
Expand Down
52 changes: 46 additions & 6 deletions pyutilib/misc/tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,8 @@ def setUp(self):
}

# Utility method for generating and validating a template description
def _validateTemplate(self, reference_template, **kwds):
test = self.config.generate_yaml_template(**kwds)
def _validateTemplate(self, config, reference_template, **kwds):
test = config.generate_yaml_template(**kwds)
width = kwds.get('width', 80)
indent = kwds.get('indent_spacing', 2)
sys.stdout.write(test)
Expand Down Expand Up @@ -183,7 +183,7 @@ def test_template_default(self):
max pipes: 2 # Maximum number of pipes to close
response time: 60.0 # Time [min] between detection and closing valves
"""
self._validateTemplate(reference_template)
self._validateTemplate(self.config, reference_template)

def test_template_3space(self):
reference_template = """# Basic configuration for Flushing models
Expand Down Expand Up @@ -215,7 +215,8 @@ def test_template_3space(self):
response time: 60.0 # Time [min] between detection and closing
# valves
"""
self._validateTemplate(reference_template, indent_spacing=3)
self._validateTemplate(self.config, reference_template,
indent_spacing=3)

def test_template_4space(self):
reference_template = """# Basic configuration for Flushing models
Expand Down Expand Up @@ -247,7 +248,8 @@ def test_template_4space(self):
response time: 60.0 # Time [min] between detection and closing
# valves
"""
self._validateTemplate(reference_template, indent_spacing=4)
self._validateTemplate(self.config, reference_template,
indent_spacing=4)

def test_template_3space_narrow(self):
reference_template = """# Basic configuration for Flushing models
Expand Down Expand Up @@ -280,7 +282,8 @@ def test_template_3space_narrow(self):
response time: 60.0 # Time [min] between detection and closing
# valves
"""
self._validateTemplate(reference_template, indent_spacing=3, width=72)
self._validateTemplate(self.config, reference_template,
indent_spacing=3, width=72)

def test_display_default(self):
reference = """network:
Expand Down Expand Up @@ -1507,5 +1510,42 @@ def test_set_value(self):
self.assertEqual(config.a_c, 20)
self.assertEqual(config.a_d_e, 30)

def test_call_options(self):
config = ConfigBlock(description="base description",
doc="base doc",
visibility=1)
config.declare("a", ConfigValue(domain=int, doc="a doc", default=1))
config.declare("b", config.get("a")(2))
config.declare("c", config.get("a")(domain=float, doc="c doc"))

reference_template = """# base description
"""
self._validateTemplate(config, reference_template)
reference_template = """# base description
a: 1
b: 2
c: 1.0
"""
self._validateTemplate(config, reference_template, visibility=1)

simple_copy = config()
self._validateTemplate(simple_copy, reference_template, visibility=1)
self.assertEqual(simple_copy._doc, "base doc")
self.assertEqual(simple_copy._description, "base description")
self.assertEqual(simple_copy._visibility, 1)

mod_copy = config(description="new description",
doc="new doc",
visibility=0)
reference_template = """# new description
a: 1
b: 2
c: 1.0
"""
self._validateTemplate(mod_copy, reference_template, visibility=0)
self.assertEqual(mod_copy._doc, "new doc")
self.assertEqual(mod_copy._description, "new description")
self.assertEqual(mod_copy._visibility, 0)

if __name__ == "__main__":
unittest.main()

0 comments on commit 5dfe8ad

Please sign in to comment.