permissive in the getattr
This commit is contained in:
parent
b3da043190
commit
a36ae7df85
4 changed files with 35 additions and 19 deletions
|
@ -42,12 +42,13 @@ def carry_out_calculation(name, option, config):
|
|||
if type(value) == tuple:
|
||||
path, check_disabled = value
|
||||
try:
|
||||
opt_value = getattr(config, path)
|
||||
#opt_value = getattr(config, path)
|
||||
opt_value = config._getattr(path, permissive=True)
|
||||
opt = config.unwrap_from_path(path)
|
||||
except PropertiesOptionError, e:
|
||||
except PropertiesOptionError, err:
|
||||
if check_disabled:
|
||||
continue
|
||||
raise PropertiesOptionError(e)
|
||||
raise PropertiesOptionError(err, err.proptype)
|
||||
is_multi = opt.is_multi()
|
||||
if is_multi:
|
||||
if opt_value != None:
|
||||
|
|
|
@ -34,6 +34,7 @@ default_owner = 'user'
|
|||
class Config(object):
|
||||
"properties attribute: the name of a property enables this property"
|
||||
_cfgimpl_properties = ['hidden', 'disabled']
|
||||
_cfgimpl_permissive = []
|
||||
"mandatory means: a mandatory option has to have a value that is not None"
|
||||
_cfgimpl_mandatory = True
|
||||
_cfgimpl_frozen = True
|
||||
|
@ -100,6 +101,11 @@ class Config(object):
|
|||
self._cfgimpl_values[child._name] = Config(child, parent=self)
|
||||
self.override(overrides)
|
||||
|
||||
def cfgimpl_set_permissive(self, permissive):
|
||||
if not isinstance(permissive, list):
|
||||
raise TypeError('permissive must be a list')
|
||||
self._cfgimpl_permissive = permissive
|
||||
|
||||
def cfgimpl_update(self):
|
||||
"""dynamically adds `Option()` or `OptionDescription()`
|
||||
"""
|
||||
|
@ -175,7 +181,7 @@ class Config(object):
|
|||
self._validate(name, getattr(self._cfgimpl_descr, name))
|
||||
self.setoption(name, value, self._cfgimpl_owner)
|
||||
|
||||
def _validate(self, name, opt_or_descr):
|
||||
def _validate(self, name, opt_or_descr, permissive=False):
|
||||
"validation for the setattr and the getattr"
|
||||
apply_requires(opt_or_descr, self)
|
||||
if not isinstance(opt_or_descr, Option) and \
|
||||
|
@ -185,6 +191,10 @@ class Config(object):
|
|||
for proper in properties:
|
||||
if not self._cfgimpl_toplevel._cfgimpl_has_property(proper):
|
||||
properties.remove(proper)
|
||||
if permissive:
|
||||
for perm in self._cfgimpl_toplevel._cfgimpl_permissive:
|
||||
if perm in properties:
|
||||
properties.remove(perm)
|
||||
if properties != []:
|
||||
raise PropertiesOptionError("trying to access"
|
||||
" to an option named: {0} with properties"
|
||||
|
@ -200,12 +210,15 @@ class Config(object):
|
|||
return False
|
||||
|
||||
def __getattr__(self, name):
|
||||
return self._getattr(name)
|
||||
|
||||
def _getattr(self, name, permissive=False):
|
||||
"attribute notation mechanism for accessing the value of an option"
|
||||
# attribute access by passing a path,
|
||||
# for instance getattr(self, "creole.general.family.adresse_ip_eth0")
|
||||
if '.' in name:
|
||||
homeconfig, name = self._cfgimpl_get_home_by_path(name)
|
||||
return getattr(homeconfig, name)
|
||||
return homeconfig._getattr(name, permissive)
|
||||
opt_or_descr = getattr(self._cfgimpl_descr, name)
|
||||
# symlink options
|
||||
if type(opt_or_descr) == SymLinkOption:
|
||||
|
@ -213,7 +226,7 @@ class Config(object):
|
|||
if name not in self._cfgimpl_values:
|
||||
raise AttributeError("%s object has no attribute %s" %
|
||||
(self.__class__, name))
|
||||
self._validate(name, opt_or_descr)
|
||||
self._validate(name, opt_or_descr, permissive)
|
||||
# special attributes
|
||||
if name.startswith('_cfgimpl_'):
|
||||
# if it were in __dict__ it would have been found already
|
||||
|
@ -271,9 +284,8 @@ class Config(object):
|
|||
raise MandatoryError("option: {0} is mandatory "
|
||||
"and shall have a value".format(name))
|
||||
# frozen and force default
|
||||
if opt_or_descr.is_forced_on_freeze():
|
||||
if not opt_or_descr.has_callback() and opt_or_descr.is_forced_on_freeze():
|
||||
return opt_or_descr.getdefault()
|
||||
|
||||
return self._cfgimpl_values[name]
|
||||
|
||||
def unwrap_from_name(self, name):
|
||||
|
|
|
@ -7,7 +7,7 @@ class ConfigError(Exception):
|
|||
class ConflictConfigError(ConfigError):
|
||||
pass
|
||||
class PropertiesOptionError(AttributeError):
|
||||
def __init__(self, msg, proptype=None):
|
||||
def __init__(self, msg, proptype):
|
||||
self.proptype = proptype
|
||||
super(PropertiesOptionError, self).__init__(msg)
|
||||
|
||||
|
|
|
@ -22,7 +22,8 @@
|
|||
# ____________________________________________________________
|
||||
from tiramisu.basetype import HiddenBaseType, DisabledBaseType
|
||||
from tiramisu.error import (ConfigError, ConflictConfigError, NotFoundError,
|
||||
RequiresError, RequirementRecursionError, MandatoryError)
|
||||
RequiresError, RequirementRecursionError, MandatoryError,
|
||||
PropertiesOptionError)
|
||||
from tiramisu.autolib import carry_out_calculation
|
||||
|
||||
requires_actions = [('hide', 'show'), ('enable', 'disable'), ('freeze', 'unfreeze')]
|
||||
|
@ -195,8 +196,7 @@ class Option(HiddenBaseType, DisabledBaseType):
|
|||
|
||||
def getcallback_value(self, config):
|
||||
return carry_out_calculation(self._name,
|
||||
option=self,
|
||||
config=config)
|
||||
option=self, config=config)
|
||||
|
||||
def getcallback_params(self):
|
||||
"if a callback has been defined, returns his arity"
|
||||
|
@ -539,15 +539,18 @@ def apply_requires(opt, config):
|
|||
"imbrication detected for option: '{0}' "
|
||||
"with requirement on: '{1}'".format(path, name))
|
||||
homeconfig, shortname = rootconfig._cfgimpl_get_home_by_path(name)
|
||||
if shortname in homeconfig._cfgimpl_values:
|
||||
value = homeconfig._cfgimpl_values[shortname]
|
||||
try:
|
||||
value = homeconfig._getattr(shortname, permissive=True)
|
||||
except PropertiesOptionError, err:
|
||||
raise NotFoundError("required option has property error: "
|
||||
"{0} {1}".format(name, err.proptype))
|
||||
except Exception, err:
|
||||
raise NotFoundError("required option not found: "
|
||||
"{0}".format(name))
|
||||
if value == expected:
|
||||
getattr(opt, action)() #.hide() or show() or...
|
||||
# FIXME generic programming opt.property_launch(action, False)
|
||||
matches = True
|
||||
else: # option doesn't exist ! should not happen...
|
||||
raise NotFoundError("required option not found: "
|
||||
"{0}".format(name))
|
||||
# no callback has been triggered, then just reverse the action
|
||||
if not matches:
|
||||
getattr(opt, reverse_actions[action])()
|
||||
|
|
Loading…
Reference in a new issue