settings are in a separate object
This commit is contained in:
parent
5969eaa2d6
commit
86f9096937
6 changed files with 143 additions and 164 deletions
|
@ -3,6 +3,7 @@ import autopath
|
||||||
from py.test import raises
|
from py.test import raises
|
||||||
from tiramisu.config import *
|
from tiramisu.config import *
|
||||||
from tiramisu.option import *
|
from tiramisu.option import *
|
||||||
|
from tiramisu.setting import settings
|
||||||
|
|
||||||
def make_description():
|
def make_description():
|
||||||
gcoption = ChoiceOption('name', 'GC name', ['ref', 'framework'], 'ref')
|
gcoption = ChoiceOption('name', 'GC name', ['ref', 'framework'], 'ref')
|
||||||
|
@ -48,25 +49,6 @@ def make_description2():
|
||||||
intoption, boolop])
|
intoption, boolop])
|
||||||
return descr
|
return descr
|
||||||
|
|
||||||
#def test_override_are_default_owner():
|
|
||||||
# "config.override() implies that the owner is 'default' again"
|
|
||||||
# descr = make_description2()
|
|
||||||
# config = Config(descr)
|
|
||||||
# config.bool = False
|
|
||||||
# # default
|
|
||||||
# assert config.gc._cfgimpl_value_owners['dummy'] == 'default'
|
|
||||||
# # user
|
|
||||||
# config.gc.dummy = True
|
|
||||||
# assert config.gc._cfgimpl_value_owners['dummy'] == 'user'
|
|
||||||
# assert config._cfgimpl_values['gc']._cfgimpl_value_owners['dummy'] == 'user'
|
|
||||||
# #Options have an available default setting and can give it back
|
|
||||||
# assert config._cfgimpl_descr._children[0]._children[1].getdefault() == False
|
|
||||||
# config.override({'gc.dummy':True})
|
|
||||||
# assert config.gc._cfgimpl_value_owners['dummy'] == 'default'
|
|
||||||
# # user again
|
|
||||||
# config.gc.dummy = False
|
|
||||||
# assert config.gc._cfgimpl_value_owners['dummy'] == 'user'
|
|
||||||
|
|
||||||
def test_has_callback():
|
def test_has_callback():
|
||||||
descr = make_description()
|
descr = make_description()
|
||||||
# here the owner is 'default'
|
# here the owner is 'default'
|
||||||
|
@ -74,7 +56,7 @@ def test_has_callback():
|
||||||
config.bool = False
|
config.bool = False
|
||||||
# because dummy has a callback
|
# because dummy has a callback
|
||||||
dummy = config.unwrap_from_path('gc.dummy')
|
dummy = config.unwrap_from_path('gc.dummy')
|
||||||
config.cfgimpl_freeze()
|
settings.freeze()
|
||||||
dummy.freeze()
|
dummy.freeze()
|
||||||
raises(TypeError, "config.gc.dummy = True")
|
raises(TypeError, "config.gc.dummy = True")
|
||||||
|
|
||||||
|
@ -83,12 +65,7 @@ def test_freeze_and_has_callback_with_setoption():
|
||||||
descr = make_description()
|
descr = make_description()
|
||||||
config = Config(descr)
|
config = Config(descr)
|
||||||
config.bool = False
|
config.bool = False
|
||||||
config.cfgimpl_freeze()
|
settings.freeze()
|
||||||
dummy = config.unwrap_from_path('gc.dummy')
|
dummy = config.unwrap_from_path('gc.dummy')
|
||||||
dummy.freeze()
|
dummy.freeze()
|
||||||
raises(TypeError, "config.gc.setoption('dummy', True, 'gen_config')")
|
raises(TypeError, "config.gc.setoption('dummy', True, 'gen_config')")
|
||||||
|
|
||||||
#def test_cannot_override():
|
|
||||||
# descr = make_description()
|
|
||||||
# config = Config(descr, bool=False)
|
|
||||||
# raises(TypeError, "config.override({'gc.dummy': True})")
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ from py.test import raises
|
||||||
|
|
||||||
from tiramisu.config import *
|
from tiramisu.config import *
|
||||||
from tiramisu.option import *
|
from tiramisu.option import *
|
||||||
|
from tiramisu.setting import settings
|
||||||
|
|
||||||
def make_description():
|
def make_description():
|
||||||
gcoption = ChoiceOption('name', 'GC name', ['ref', 'framework'], 'ref')
|
gcoption = ChoiceOption('name', 'GC name', ['ref', 'framework'], 'ref')
|
||||||
|
@ -74,7 +75,7 @@ def test_frozen_value():
|
||||||
s = StrOption("string", "", default="string")
|
s = StrOption("string", "", default="string")
|
||||||
descr = OptionDescription("options", "", [s])
|
descr = OptionDescription("options", "", [s])
|
||||||
config = Config(descr)
|
config = Config(descr)
|
||||||
config.cfgimpl_freeze()
|
settings.freeze()
|
||||||
s.freeze()
|
s.freeze()
|
||||||
raises(TypeError, 'config.string = "egg"')
|
raises(TypeError, 'config.string = "egg"')
|
||||||
|
|
||||||
|
@ -82,7 +83,7 @@ def test_freeze():
|
||||||
"freeze a whole configuration object"
|
"freeze a whole configuration object"
|
||||||
descr = make_description()
|
descr = make_description()
|
||||||
conf = Config(descr)
|
conf = Config(descr)
|
||||||
conf.cfgimpl_freeze()
|
settings.freeze()
|
||||||
name = conf.unwrap_from_path("gc.name")
|
name = conf.unwrap_from_path("gc.name")
|
||||||
name.freeze()
|
name.freeze()
|
||||||
raises(TypeError, "conf.gc.name = 'framework'")
|
raises(TypeError, "conf.gc.name = 'framework'")
|
||||||
|
@ -133,4 +134,3 @@ def test_with_many_subgroups():
|
||||||
assert name == "booltwo"
|
assert name == "booltwo"
|
||||||
option = getattr(homeconfig._cfgimpl_descr, name)
|
option = getattr(homeconfig._cfgimpl_descr, name)
|
||||||
assert option._is_hidden()
|
assert option._is_hidden()
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ from py.test import raises
|
||||||
|
|
||||||
from tiramisu.config import *
|
from tiramisu.config import *
|
||||||
from tiramisu.option import *
|
from tiramisu.option import *
|
||||||
|
from tiramisu.setting import settings
|
||||||
|
|
||||||
def make_description():
|
def make_description():
|
||||||
gcoption = ChoiceOption('name', 'GC name', ['ref', 'framework'], 'ref')
|
gcoption = ChoiceOption('name', 'GC name', ['ref', 'framework'], 'ref')
|
||||||
|
@ -39,6 +40,6 @@ def test_root_config_answers_ok():
|
||||||
boolop = BoolOption('boolop', 'Test boolean option op', default=True)
|
boolop = BoolOption('boolop', 'Test boolean option op', default=True)
|
||||||
descr = OptionDescription('tiramisu', '', [gcdummy, boolop])
|
descr = OptionDescription('tiramisu', '', [gcdummy, boolop])
|
||||||
cfg = Config(descr)
|
cfg = Config(descr)
|
||||||
cfg.cfgimpl_enable_property('hiddend') #cfgimpl_hide()
|
settings.enable_property('hiddend') #cfgimpl_hide()
|
||||||
assert cfg.dummy == False
|
assert cfg.dummy == False
|
||||||
assert cfg.boolop == True
|
assert cfg.boolop == True
|
||||||
|
|
|
@ -26,23 +26,11 @@ from tiramisu.error import (PropertiesOptionError, ConfigError, NotFoundError,
|
||||||
MandatoryError, MethodCallError, NoValueReturned)
|
MandatoryError, MethodCallError, NoValueReturned)
|
||||||
from tiramisu.option import (OptionDescription, Option, SymLinkOption,
|
from tiramisu.option import (OptionDescription, Option, SymLinkOption,
|
||||||
group_types, Multi, apply_requires)
|
group_types, Multi, apply_requires)
|
||||||
|
from tiramisu.setting import settings
|
||||||
# ______________________________________________________________________
|
|
||||||
# generic owner. 'default' is the general config owner after init time
|
|
||||||
default_owner = 'user'
|
|
||||||
|
|
||||||
# ____________________________________________________________
|
# ____________________________________________________________
|
||||||
class Config(object):
|
class Config(object):
|
||||||
"main configuration management entry"
|
"main configuration management entry"
|
||||||
#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
|
|
||||||
#enables validation function for options if set
|
|
||||||
_cfgimpl_validator = False
|
|
||||||
_cfgimpl_owner = default_owner
|
|
||||||
_cfgimpl_toplevel = None
|
_cfgimpl_toplevel = None
|
||||||
|
|
||||||
def __init__(self, descr, parent=None):
|
def __init__(self, descr, parent=None):
|
||||||
|
@ -62,7 +50,6 @@ class Config(object):
|
||||||
self._cfgimpl_warnings = []
|
self._cfgimpl_warnings = []
|
||||||
self._cfgimpl_toplevel = self._cfgimpl_get_toplevel()
|
self._cfgimpl_toplevel = self._cfgimpl_get_toplevel()
|
||||||
'`freeze()` allows us to carry out this calculation again if necessary'
|
'`freeze()` allows us to carry out this calculation again if necessary'
|
||||||
self._cfgimpl_frozen = self._cfgimpl_toplevel._cfgimpl_frozen
|
|
||||||
self._cfgimpl_build()
|
self._cfgimpl_build()
|
||||||
|
|
||||||
def _validate_duplicates(self, children):
|
def _validate_duplicates(self, children):
|
||||||
|
@ -100,11 +87,6 @@ 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()`
|
||||||
"""
|
"""
|
||||||
|
@ -123,38 +105,6 @@ class Config(object):
|
||||||
if child._name not in self._cfgimpl_values:
|
if child._name not in self._cfgimpl_values:
|
||||||
self._cfgimpl_values[child._name] = Config(child, parent=self)
|
self._cfgimpl_values[child._name] = Config(child, parent=self)
|
||||||
|
|
||||||
def cfgimpl_set_owner(self, owner):
|
|
||||||
":param owner: sets the default value for owner at the Config level"
|
|
||||||
self._cfgimpl_owner = owner
|
|
||||||
for child in self._cfgimpl_descr._children:
|
|
||||||
if isinstance(child, OptionDescription):
|
|
||||||
self._cfgimpl_values[child._name].cfgimpl_set_owner(owner)
|
|
||||||
# ____________________________________________________________
|
|
||||||
# properties methods
|
|
||||||
def _cfgimpl_has_properties(self):
|
|
||||||
"has properties means the Config's properties attribute is not empty"
|
|
||||||
return bool(len(self._cfgimpl_properties))
|
|
||||||
|
|
||||||
def _cfgimpl_has_property(self, propname):
|
|
||||||
"""has property propname in the Config's properties attribute
|
|
||||||
:param property: string wich is the name of the property"""
|
|
||||||
return propname in self._cfgimpl_properties
|
|
||||||
|
|
||||||
def cfgimpl_enable_property(self, propname):
|
|
||||||
"puts property propname in the Config's properties attribute"
|
|
||||||
if self._cfgimpl_parent != None:
|
|
||||||
raise MethodCallError("this method root_hide() shall not be"
|
|
||||||
"used with non-root Config() object")
|
|
||||||
if propname not in self._cfgimpl_properties:
|
|
||||||
self._cfgimpl_properties.append(propname)
|
|
||||||
|
|
||||||
def cfgimpl_disable_property(self, propname):
|
|
||||||
"deletes property propname in the Config's properties attribute"
|
|
||||||
if self._cfgimpl_parent != None:
|
|
||||||
raise MethodCallError("this method root_hide() shall not be"
|
|
||||||
"used with non-root Config() object")
|
|
||||||
if self._cfgimpl_has_property(propname):
|
|
||||||
self._cfgimpl_properties.remove(propname)
|
|
||||||
# ____________________________________________________________
|
# ____________________________________________________________
|
||||||
# attribute methods
|
# attribute methods
|
||||||
def __setattr__(self, name, value):
|
def __setattr__(self, name, value):
|
||||||
|
@ -167,7 +117,7 @@ class Config(object):
|
||||||
return setattr(homeconfig, name, value)
|
return setattr(homeconfig, name, value)
|
||||||
if type(getattr(self._cfgimpl_descr, name)) != SymLinkOption:
|
if type(getattr(self._cfgimpl_descr, name)) != SymLinkOption:
|
||||||
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, settings.owner)
|
||||||
|
|
||||||
def _validate(self, name, opt_or_descr, permissive=False):
|
def _validate(self, name, opt_or_descr, permissive=False):
|
||||||
"validation for the setattr and the getattr"
|
"validation for the setattr and the getattr"
|
||||||
|
@ -177,10 +127,10 @@ class Config(object):
|
||||||
raise TypeError('Unexpected object: {0}'.format(repr(opt_or_descr)))
|
raise TypeError('Unexpected object: {0}'.format(repr(opt_or_descr)))
|
||||||
properties = copy(opt_or_descr.properties)
|
properties = copy(opt_or_descr.properties)
|
||||||
for proper in copy(properties):
|
for proper in copy(properties):
|
||||||
if not self._cfgimpl_toplevel._cfgimpl_has_property(proper):
|
if not settings.has_property(proper):
|
||||||
properties.remove(proper)
|
properties.remove(proper)
|
||||||
if permissive:
|
if permissive:
|
||||||
for perm in self._cfgimpl_toplevel._cfgimpl_permissive:
|
for perm in settings.permissive:
|
||||||
if perm in properties:
|
if perm in properties:
|
||||||
properties.remove(perm)
|
properties.remove(perm)
|
||||||
if properties != []:
|
if properties != []:
|
||||||
|
@ -199,8 +149,7 @@ class Config(object):
|
||||||
|
|
||||||
def _test_mandatory(self, path, opt):
|
def _test_mandatory(self, path, opt):
|
||||||
# mandatory options
|
# mandatory options
|
||||||
homeconfig = self._cfgimpl_get_toplevel()
|
mandatory = settings.mandatory
|
||||||
mandatory = homeconfig._cfgimpl_mandatory
|
|
||||||
if opt.is_mandatory() and mandatory:
|
if opt.is_mandatory() and mandatory:
|
||||||
if self._is_empty(opt) and \
|
if self._is_empty(opt) and \
|
||||||
opt.is_empty_by_default():
|
opt.is_empty_by_default():
|
||||||
|
@ -215,9 +164,9 @@ class Config(object):
|
||||||
attribute notation mechanism for accessing the value of an option
|
attribute notation mechanism for accessing the value of an option
|
||||||
:param name: attribute name
|
:param name: attribute name
|
||||||
:param permissive: permissive doesn't raise some property error
|
:param permissive: permissive doesn't raise some property error
|
||||||
(see ``_cfgimpl_permissive``)
|
(see ``settings.permissive``)
|
||||||
:return: option's value if name is an option name, OptionDescription
|
:return: option's value if name is an option name, OptionDescription
|
||||||
otherwise
|
otherwise
|
||||||
"""
|
"""
|
||||||
# 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")
|
||||||
|
@ -250,9 +199,9 @@ class Config(object):
|
||||||
return value
|
return value
|
||||||
else:
|
else:
|
||||||
return value
|
return value
|
||||||
rootconfig = self._cfgimpl_get_toplevel()
|
|
||||||
try:
|
try:
|
||||||
result = opt_or_descr.getcallback_value(rootconfig)
|
result = opt_or_descr.getcallback_value(
|
||||||
|
self._cfgimpl_get_toplevel())
|
||||||
except NoValueReturned, err:
|
except NoValueReturned, err:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
|
@ -267,7 +216,7 @@ class Config(object):
|
||||||
' for option {0} : shall not be a list'.format(name))
|
' for option {0} : shall not be a list'.format(name))
|
||||||
_result = result
|
_result = result
|
||||||
if _result != None and not opt_or_descr.validate(_result,
|
if _result != None and not opt_or_descr.validate(_result,
|
||||||
rootconfig._cfgimpl_validator):
|
settings.validator):
|
||||||
raise ConfigError('invalid calculated value returned'
|
raise ConfigError('invalid calculated value returned'
|
||||||
' for option {0}'.format(name))
|
' for option {0}'.format(name))
|
||||||
self._cfgimpl_values[name] = _result
|
self._cfgimpl_values[name] = _result
|
||||||
|
@ -327,7 +276,7 @@ class Config(object):
|
||||||
child = getattr(self._cfgimpl_descr, name)
|
child = getattr(self._cfgimpl_descr, name)
|
||||||
if type(child) != SymLinkOption:
|
if type(child) != SymLinkOption:
|
||||||
if who == None:
|
if who == None:
|
||||||
who = self._cfgimpl_owner
|
who = settings.owner
|
||||||
if child.is_multi():
|
if child.is_multi():
|
||||||
if type(value) != Multi:
|
if type(value) != Multi:
|
||||||
if type(value) == list:
|
if type(value) == list:
|
||||||
|
@ -361,7 +310,7 @@ class Config(object):
|
||||||
pass
|
pass
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
raise e # HiddenOptionError or DisabledOptionError
|
raise e # HiddenOptionError or DisabledOptionError
|
||||||
homeconfig.setoption(name, value, self._cfgimpl_owner)
|
homeconfig.setoption(name, value, settings.owner)
|
||||||
elif len(candidates) > 1:
|
elif len(candidates) > 1:
|
||||||
raise AmbigousOptionError(
|
raise AmbigousOptionError(
|
||||||
'more than one option that ends with %s' % (key, ))
|
'more than one option that ends with %s' % (key, ))
|
||||||
|
@ -433,64 +382,6 @@ class Config(object):
|
||||||
"Config implements its own warning pile"
|
"Config implements its own warning pile"
|
||||||
return self._cfgimpl_get_toplevel()._cfgimpl_warnings
|
return self._cfgimpl_get_toplevel()._cfgimpl_warnings
|
||||||
# ____________________________________________________________
|
# ____________________________________________________________
|
||||||
# Config()'s status
|
|
||||||
def cfgimpl_freeze(self):
|
|
||||||
"cannot modify the frozen `Option`'s"
|
|
||||||
rootconfig = self._cfgimpl_get_toplevel()
|
|
||||||
rootconfig._cfgimpl_frozen = True
|
|
||||||
self._cfgimpl_frozen = True
|
|
||||||
|
|
||||||
def cfgimpl_unfreeze(self):
|
|
||||||
"can modify the Options that are frozen"
|
|
||||||
rootconfig = self._cfgimpl_get_toplevel()
|
|
||||||
rootconfig._cfgimpl_frozen = False
|
|
||||||
self._cfgimpl_frozen = False
|
|
||||||
|
|
||||||
def is_frozen(self):
|
|
||||||
"freeze flag at Config level"
|
|
||||||
rootconfig = self._cfgimpl_get_toplevel()
|
|
||||||
return rootconfig._cfgimpl_frozen
|
|
||||||
|
|
||||||
def cfgimpl_read_only(self):
|
|
||||||
"convenience method to freeze, hidde and disable"
|
|
||||||
self.cfgimpl_freeze()
|
|
||||||
rootconfig = self._cfgimpl_get_toplevel()
|
|
||||||
rootconfig.cfgimpl_disable_property('hidden')
|
|
||||||
rootconfig.cfgimpl_enable_property('disabled')
|
|
||||||
rootconfig._cfgimpl_mandatory = True
|
|
||||||
rootconfig._cfgimpl_validator = True
|
|
||||||
|
|
||||||
def cfgimpl_read_write(self):
|
|
||||||
"convenience method to freeze, hidde and disable"
|
|
||||||
self.cfgimpl_freeze()
|
|
||||||
rootconfig = self._cfgimpl_get_toplevel()
|
|
||||||
rootconfig.cfgimpl_enable_property('hidden')
|
|
||||||
rootconfig.cfgimpl_enable_property('disabled')
|
|
||||||
rootconfig._cfgimpl_mandatory = False
|
|
||||||
|
|
||||||
def cfgimpl_non_mandatory(self):
|
|
||||||
"""mandatory at the Config level means that the Config raises an error
|
|
||||||
if a mandatory option is found"""
|
|
||||||
if self._cfgimpl_parent != None:
|
|
||||||
raise MethodCallError("this method root_mandatory shall"
|
|
||||||
" not be used with non-root Confit() object")
|
|
||||||
rootconfig = self._cfgimpl_get_toplevel()
|
|
||||||
rootconfig._cfgimpl_mandatory = False
|
|
||||||
|
|
||||||
def cfgimpl_mandatory(self):
|
|
||||||
"""mandatory at the Config level means that the Config raises an error
|
|
||||||
if a mandatory option is found"""
|
|
||||||
if self._cfgimpl_parent != None:
|
|
||||||
raise MethodCallError("this method root_mandatory shall"
|
|
||||||
" not be used with non-root Confit() object")
|
|
||||||
rootconfig = self._cfgimpl_get_toplevel()
|
|
||||||
rootconfig._cfgimpl_mandatory = True
|
|
||||||
|
|
||||||
def is_mandatory(self):
|
|
||||||
"all mandatory Options shall have a value"
|
|
||||||
rootconfig = self._cfgimpl_get_toplevel()
|
|
||||||
return rootconfig._cfgimpl_mandatory
|
|
||||||
# ____________________________________________________________
|
|
||||||
def getkey(self):
|
def getkey(self):
|
||||||
return self._cfgimpl_descr.getkey(self)
|
return self._cfgimpl_descr.getkey(self)
|
||||||
|
|
||||||
|
@ -685,8 +576,8 @@ def mandatory_warnings(config):
|
||||||
|
|
||||||
:returns: generator of mandatory Option's path
|
:returns: generator of mandatory Option's path
|
||||||
"""
|
"""
|
||||||
mandatory = config._cfgimpl_get_toplevel()._cfgimpl_mandatory
|
mandatory = settings.mandatory
|
||||||
config._cfgimpl_get_toplevel()._cfgimpl_mandatory = True
|
settings.mandatory = True
|
||||||
for path in config._cfgimpl_descr.getpaths(include_groups=True):
|
for path in config._cfgimpl_descr.getpaths(include_groups=True):
|
||||||
try:
|
try:
|
||||||
value = config._getattr(path, permissive=True)
|
value = config._getattr(path, permissive=True)
|
||||||
|
@ -694,4 +585,4 @@ def mandatory_warnings(config):
|
||||||
yield path
|
yield path
|
||||||
except PropertiesOptionError:
|
except PropertiesOptionError:
|
||||||
pass
|
pass
|
||||||
config._cfgimpl_get_toplevel()._cfgimpl_mandatory = mandatory
|
settings.mandatory = mandatory
|
||||||
|
|
|
@ -26,6 +26,7 @@ from tiramisu.error import (ConfigError, ConflictConfigError, NotFoundError,
|
||||||
RequiresError, RequirementRecursionError, MandatoryError,
|
RequiresError, RequirementRecursionError, MandatoryError,
|
||||||
PropertiesOptionError)
|
PropertiesOptionError)
|
||||||
from tiramisu.autolib import carry_out_calculation
|
from tiramisu.autolib import carry_out_calculation
|
||||||
|
from tiramisu.setting import settings
|
||||||
|
|
||||||
requires_actions = [('hide', 'show'), ('enable', 'disable'), ('freeze', 'unfreeze')]
|
requires_actions = [('hide', 'show'), ('enable', 'disable'), ('freeze', 'unfreeze')]
|
||||||
|
|
||||||
|
@ -63,7 +64,7 @@ class Multi(list):
|
||||||
|
|
||||||
def setoption(self, value, key=None, who=None):
|
def setoption(self, value, key=None, who=None):
|
||||||
if who is None:
|
if who is None:
|
||||||
who = self.config._cfgimpl_owner
|
who = settings.owner
|
||||||
if value != None:
|
if value != None:
|
||||||
if not self.child._validate(value):
|
if not self.child._validate(value):
|
||||||
raise ConfigError("invalid value {0} "
|
raise ConfigError("invalid value {0} "
|
||||||
|
@ -78,7 +79,7 @@ class Multi(list):
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def pop(self, key):
|
def pop(self, key):
|
||||||
self.child.setowner(self.config, self.config._cfgimpl_owner)
|
self.child.setowner(self.config, settings.owner)
|
||||||
super(Multi, self).pop(key)
|
super(Multi, self).pop(key)
|
||||||
# ____________________________________________________________
|
# ____________________________________________________________
|
||||||
#
|
#
|
||||||
|
@ -257,7 +258,7 @@ class Option(HiddenBaseType, DisabledBaseType):
|
||||||
:type who: string """
|
:type who: string """
|
||||||
name = self._name
|
name = self._name
|
||||||
rootconfig = config._cfgimpl_get_toplevel()
|
rootconfig = config._cfgimpl_get_toplevel()
|
||||||
if not self.validate(value, rootconfig._cfgimpl_validator):
|
if not self.validate(value, settings.validator):
|
||||||
raise ConfigError('invalid value %s for option %s' % (value, name))
|
raise ConfigError('invalid value %s for option %s' % (value, name))
|
||||||
if self.is_mandatory():
|
if self.is_mandatory():
|
||||||
# value shall not be '' for a mandatory option
|
# value shall not be '' for a mandatory option
|
||||||
|
@ -266,14 +267,14 @@ class Option(HiddenBaseType, DisabledBaseType):
|
||||||
value = None
|
value = None
|
||||||
if self.is_multi() and '' in value:
|
if self.is_multi() and '' in value:
|
||||||
value = Multi([{'': None}.get(i, i) for i in value], config, self)
|
value = Multi([{'': None}.get(i, i) for i in value], config, self)
|
||||||
if config.is_mandatory() and ((self.is_multi() and value == []) or \
|
if settings.is_mandatory() and ((self.is_multi() and value == []) or \
|
||||||
(not self.is_multi() and value is None)):
|
(not self.is_multi() and value is None)):
|
||||||
raise MandatoryError('cannot change the value to %s for '
|
raise MandatoryError('cannot change the value to %s for '
|
||||||
'option %s' % (value, name))
|
'option %s' % (value, name))
|
||||||
if name not in config._cfgimpl_values:
|
if name not in config._cfgimpl_values:
|
||||||
raise AttributeError('unknown option %s' % (name))
|
raise AttributeError('unknown option %s' % (name))
|
||||||
|
|
||||||
if config.is_frozen() and self.is_frozen():
|
if settings.is_frozen() and self.is_frozen():
|
||||||
raise TypeError('cannot change the value to %s for '
|
raise TypeError('cannot change the value to %s for '
|
||||||
'option %s this option is frozen' % (str(value), name))
|
'option %s this option is frozen' % (str(value), name))
|
||||||
apply_requires(self, config)
|
apply_requires(self, config)
|
||||||
|
|
109
tiramisu/setting.py
Normal file
109
tiramisu/setting.py
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"sets the options of the configuration objects Config object itself"
|
||||||
|
# Copyright (C) 2012 Team tiramisu (see AUTHORS for all contributors)
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
#
|
||||||
|
# The original `Config` design model is unproudly borrowed from
|
||||||
|
# the rough pypy's guys: http://codespeak.net/svn/pypy/dist/pypy/config/
|
||||||
|
# the whole pypy projet is under MIT licence
|
||||||
|
# ____________________________________________________________
|
||||||
|
|
||||||
|
class Setting():
|
||||||
|
"``Config()``'s configuration options"
|
||||||
|
# properties attribute: the name of a property enables this property
|
||||||
|
properties = ['hidden', 'disabled']
|
||||||
|
# overrides the validations in the acces of the option values
|
||||||
|
permissive = []
|
||||||
|
# a mandatory option must have a value that is not None
|
||||||
|
mandatory = True
|
||||||
|
frozen = True
|
||||||
|
# enables validation function for options if set
|
||||||
|
validator = False
|
||||||
|
# generic owner. 'default' is the general config owner after init time
|
||||||
|
owner = 'user'
|
||||||
|
# ____________________________________________________________
|
||||||
|
# properties methods
|
||||||
|
def has_properties(self):
|
||||||
|
"has properties means the Config's properties attribute is not empty"
|
||||||
|
return bool(len(self.properties))
|
||||||
|
|
||||||
|
def has_property(self, propname):
|
||||||
|
"""has property propname in the Config's properties attribute
|
||||||
|
:param property: string wich is the name of the property"""
|
||||||
|
return propname in self.properties
|
||||||
|
|
||||||
|
def enable_property(self, propname):
|
||||||
|
"puts property propname in the Config's properties attribute"
|
||||||
|
if propname not in self.properties:
|
||||||
|
self.properties.append(propname)
|
||||||
|
|
||||||
|
def disable_property(self, propname):
|
||||||
|
"deletes property propname in the Config's properties attribute"
|
||||||
|
if self.has_property(propname):
|
||||||
|
self.properties.remove(propname)
|
||||||
|
|
||||||
|
def set_permissive(self, permissive):
|
||||||
|
if not isinstance(permissive, list):
|
||||||
|
raise TypeError('permissive must be a list')
|
||||||
|
self.permissive = permissive
|
||||||
|
|
||||||
|
def read_only(self):
|
||||||
|
"convenience method to freeze, hidde and disable"
|
||||||
|
self.freeze()
|
||||||
|
self.disable_property('hidden')
|
||||||
|
self.enable_property('disabled')
|
||||||
|
self.mandatory = True
|
||||||
|
self.validator = True
|
||||||
|
|
||||||
|
def read_write(self):
|
||||||
|
"convenience method to freeze, hidde and disable"
|
||||||
|
self.freeze()
|
||||||
|
self.enable_property('hidden')
|
||||||
|
self.enable_property('disabled')
|
||||||
|
self.mandatory = False
|
||||||
|
|
||||||
|
def non_mandatory(self):
|
||||||
|
"""mandatory at the Config level means that the Config raises an error
|
||||||
|
if a mandatory option is found"""
|
||||||
|
self.mandatory = False
|
||||||
|
|
||||||
|
def mandatory(self):
|
||||||
|
"""mandatory at the Config level means that the Config raises an error
|
||||||
|
if a mandatory option is found"""
|
||||||
|
self.mandatory = True
|
||||||
|
|
||||||
|
def is_mandatory(self):
|
||||||
|
"all mandatory Options shall have a value"
|
||||||
|
return self.mandatory
|
||||||
|
|
||||||
|
def freeze(self):
|
||||||
|
"cannot modify the frozen `Option`'s"
|
||||||
|
self.frozen = True
|
||||||
|
|
||||||
|
def unfreeze(self):
|
||||||
|
"can modify the Options that are frozen"
|
||||||
|
self.frozen = False
|
||||||
|
|
||||||
|
def is_frozen(self):
|
||||||
|
"freeze flag at Config level"
|
||||||
|
return self.frozen
|
||||||
|
|
||||||
|
def set_owner(self, owner):
|
||||||
|
":param owner: sets the default value for owner at the Config level"
|
||||||
|
self.owner = owner
|
||||||
|
|
||||||
|
# Setting is actually a singleton
|
||||||
|
settings = Setting()
|
Loading…
Reference in a new issue