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