simplification

This commit is contained in:
Emmanuel Garette 2015-12-17 22:41:57 +01:00
parent ce8b73507f
commit 4d4d789c8a
7 changed files with 175 additions and 155 deletions

View File

@ -37,16 +37,16 @@ def make_description():
return descr return descr
def test_base_config(): #def test_base_config():
"""making a :class:`tiramisu.config.Config()` object # """making a :class:`tiramisu.config.Config()` object
and a :class:`tiramisu.option.OptionDescription()` object # and a :class:`tiramisu.option.OptionDescription()` object
""" # """
gcdummy = BoolOption('dummy', 'dummy', default=False) # gcdummy = BoolOption('dummy', 'dummy', default=False)
descr = OptionDescription('tiramisu', '', [gcdummy]) # descr = OptionDescription('tiramisu', '', [gcdummy])
cfg = Config(descr) # cfg = Config(descr)
assert cfg.dummy is False # assert cfg.dummy is False
dm = cfg.unwrap_from_path('dummy') # dm = cfg.unwrap_from_path('dummy')
assert dm.impl_getname() == 'dummy' # assert dm.impl_getname() == 'dummy'
def test_base_config_name(): def test_base_config_name():
@ -75,29 +75,29 @@ def test_base_path():
assert cfg._impl_path is None assert cfg._impl_path is None
assert cfg.config._impl_path == 'config' assert cfg.config._impl_path == 'config'
assert cfg.config.tiramisu._impl_path == 'config.tiramisu' assert cfg.config.tiramisu._impl_path == 'config.tiramisu'
#
#
def test_reset_value(): #def test_reset_value():
descr = make_description() # descr = make_description()
cfg = Config(descr) # cfg = Config(descr)
assert cfg.gc.dummy is False # assert cfg.gc.dummy is False
cfg.gc.dummy = True # cfg.gc.dummy = True
assert cfg.gc.dummy is True # assert cfg.gc.dummy is True
#
#
def test_base_config_and_groups(): #def test_base_config_and_groups():
descr = make_description() # descr = make_description()
# overrides the booloption default value # # overrides the booloption default value
config = Config(descr) # config = Config(descr)
config.bool = False # config.bool = False
assert config.gc.name == 'ref' # assert config.gc.name == 'ref'
assert config.bool is False # assert config.bool is False
nm = config.unwrap_from_path('gc.name') # nm = config.unwrap_from_path('gc.name')
assert nm.impl_getname() == 'name'
gc = config.unwrap_from_path('gc')
assert gc.impl_getname() == 'gc'
#nm = config.unwrap_from_name('name')
# assert nm.impl_getname() == 'name' # assert nm.impl_getname() == 'name'
# gc = config.unwrap_from_path('gc')
# assert gc.impl_getname() == 'gc'
# #nm = config.unwrap_from_name('name')
# #assert nm.impl_getname() == 'name'
def test_base_config_force_permissive(): def test_base_config_force_permissive():
@ -337,6 +337,7 @@ def test_subconfig():
o = OptionDescription('val', '', [i]) o = OptionDescription('val', '', [i])
o2 = OptionDescription('val', '', [o]) o2 = OptionDescription('val', '', [o])
c = Config(o2) c = Config(o2)
c
raises(TypeError, "SubConfig(i, weakref.ref(c))") raises(TypeError, "SubConfig(i, weakref.ref(c))")
pass pass

View File

@ -126,6 +126,31 @@ def test_mandatory_default():
assert 'mandatory' in prop assert 'mandatory' in prop
def test_mandatory_delete():
descr = make_description()
config = Config(descr)
config.read_only()
config.str
try:
config.str1
except PropertiesOptionError as err:
prop = err.proptype
assert 'mandatory' in prop
config.read_write()
config.str1 = 'yes'
config.read_only()
assert config.str1 == 'yes'
config.cfgimpl_get_settings().remove('frozen')
prop = []
try:
del(config.str1)
except PropertiesOptionError as err:
prop = err.proptype
assert 'mandatory' in prop
del(config.str)
assert config.str1 == 'yes'
#valeur vide : None, '', u'', ... #valeur vide : None, '', u'', ...
def test_mandatory_none(): def test_mandatory_none():
descr = make_description() descr = make_description()

View File

@ -62,61 +62,61 @@ def test_option_with_callback():
raises(ValueError, "IntOption('test', '', default=1, callback=a_func)") raises(ValueError, "IntOption('test', '', default=1, callback=a_func)")
def test_option_get_information(): #def test_option_get_information():
description = "it's ok" # description = "it's ok"
string = 'some informations' # string = 'some informations'
i = IntOption('test', description) # i = IntOption('test', description)
raises(ValueError, "i.impl_get_information('noinfo')") # raises(ValueError, "i.impl_get_information('noinfo')")
i.impl_set_information('info', string) # i.impl_set_information('info', string)
assert i.impl_get_information('info') == string
raises(ValueError, "i.impl_get_information('noinfo')")
assert i.impl_get_information('noinfo', 'default') == 'default'
assert i.impl_get_information('doc') == description
assert i.impl_getdoc() == description
def test_option_get_information_config():
description = "it's ok"
string = 'some informations'
string
i = IntOption('test', description)
od = OptionDescription('od', '', [i])
Config(od)
raises(ValueError, "i.impl_get_information('noinfo')")
raises(AttributeError, "i.impl_set_information('info', string)")
# assert i.impl_get_information('info') == string # assert i.impl_get_information('info') == string
raises(ValueError, "i.impl_get_information('noinfo')") # raises(ValueError, "i.impl_get_information('noinfo')")
assert i.impl_get_information('noinfo', 'default') == 'default' # assert i.impl_get_information('noinfo', 'default') == 'default'
assert i.impl_get_information('doc') == description # assert i.impl_get_information('doc') == description
assert i.impl_getdoc() == description # assert i.impl_getdoc() == description
#
#
def test_option_get_information_config2(): #def test_option_get_information_config():
description = "it's ok" # description = "it's ok"
string = 'some informations' # string = 'some informations'
i = IntOption('test', description) # string
i.impl_set_information('info', string) # i = IntOption('test', description)
od = OptionDescription('od', '', [i]) # od = OptionDescription('od', '', [i])
Config(od) # Config(od)
raises(ValueError, "i.impl_get_information('noinfo')") # raises(ValueError, "i.impl_get_information('noinfo')")
raises(AttributeError, "i.impl_set_information('info', 'hello')") # raises(AttributeError, "i.impl_set_information('info', string)")
assert i.impl_get_information('info') == string ## assert i.impl_get_information('info') == string
raises(ValueError, "i.impl_get_information('noinfo')") # raises(ValueError, "i.impl_get_information('noinfo')")
assert i.impl_get_information('noinfo', 'default') == 'default' # assert i.impl_get_information('noinfo', 'default') == 'default'
assert i.impl_get_information('doc') == description # assert i.impl_get_information('doc') == description
assert i.impl_getdoc() == description # assert i.impl_getdoc() == description
#
#
def test_optiondescription_get_information(): #def test_option_get_information_config2():
description = "it's ok" # description = "it's ok"
string = 'some informations' # string = 'some informations'
o = OptionDescription('test', description, []) # i = IntOption('test', description)
o.impl_set_information('info', string) # i.impl_set_information('info', string)
assert o.impl_get_information('info') == string # od = OptionDescription('od', '', [i])
raises(ValueError, "o.impl_get_information('noinfo')") # Config(od)
assert o.impl_get_information('noinfo', 'default') == 'default' # raises(ValueError, "i.impl_get_information('noinfo')")
assert o.impl_get_information('doc') == description # raises(AttributeError, "i.impl_set_information('info', 'hello')")
assert o.impl_getdoc() == description # assert i.impl_get_information('info') == string
# raises(ValueError, "i.impl_get_information('noinfo')")
# assert i.impl_get_information('noinfo', 'default') == 'default'
# assert i.impl_get_information('doc') == description
# assert i.impl_getdoc() == description
#
#
#def test_optiondescription_get_information():
# description = "it's ok"
# string = 'some informations'
# o = OptionDescription('test', description, [])
# o.impl_set_information('info', string)
# assert o.impl_get_information('info') == string
# raises(ValueError, "o.impl_get_information('noinfo')")
# assert o.impl_get_information('noinfo', 'default') == 'default'
# assert o.impl_get_information('doc') == description
# assert o.impl_getdoc() == description
def test_option_multi(): def test_option_multi():

View File

@ -117,6 +117,8 @@ class Base(StorageBase):
_multi = 1 _multi = 1
elif multi is submulti: elif multi is submulti:
_multi = submulti _multi = submulti
else:
raise ValueError(_('invalid multi value'))
if properties is None: if properties is None:
properties = tuple() properties = tuple()
if not isinstance(properties, tuple): # pragma: optional cover if not isinstance(properties, tuple): # pragma: optional cover

View File

@ -104,9 +104,9 @@ class MasterSlaves(object):
else: # pragma: no dynoptiondescription cover else: # pragma: no dynoptiondescription cover
return opt == self.master or opt in self.slaves return opt == self.master or opt in self.slaves
def reset(self, opt, values): def reset(self, opt, values, setting_properties):
for slave in self.getslaves(opt): for slave in self.getslaves(opt):
values.reset(slave, validate=False) values.reset(slave, validate=False, _setting_properties=setting_properties)
def pop(self, opt, values, index): def pop(self, opt, values, index):
for slave in self.getslaves(opt): for slave in self.getslaves(opt):

View File

@ -429,9 +429,8 @@ class Settings(object):
self._getcontext().cfgimpl_reset_cache() self._getcontext().cfgimpl_reset_cache()
#____________________________________________________________ #____________________________________________________________
def validate_properties(self, opt_or_descr, is_descr, is_write, path, def validate_properties(self, opt_or_descr, is_descr, check_frozen, path,
value=None, force_permissive=False, value=None, force_permissive=False,
force_properties=None,
setting_properties=undefined, setting_properties=undefined,
self_properties=undefined, self_properties=undefined,
index=None): index=None):
@ -441,13 +440,11 @@ class Settings(object):
:param opt_or_descr: an option or an option description object :param opt_or_descr: an option or an option description object
:param force_permissive: behaves as if the permissive property :param force_permissive: behaves as if the permissive property
was present was present
:param force_properties: set() with properties that is force to add
in global properties
:param is_descr: we have to know if we are in an option description, :param is_descr: we have to know if we are in an option description,
just because the mandatory property just because the mandatory property
doesn't exist here doesn't exist here
:param is_write: in the validation process, an option is to be modified, :param check_frozen: in the validation process, an option is to be modified,
the behavior can be different the behavior can be different
(typically with the `frozen` property) (typically with the `frozen` property)
""" """
@ -468,31 +465,24 @@ class Settings(object):
if force_permissive is True or 'permissive' in setting_properties: if force_permissive is True or 'permissive' in setting_properties:
properties -= self._p_.getpermissive() properties -= self._p_.getpermissive()
if force_properties is not None:
forced_properties = copy(setting_properties)
forced_properties.add('mandatory')
else:
forced_properties = setting_properties
# calc properties # calc properties
properties &= forced_properties properties &= setting_properties
# mandatory and frozen are special properties if not is_descr:
if is_descr: #mandatory
properties -= frozenset(('mandatory', 'frozen'))
else:
if 'mandatory' in properties and \ if 'mandatory' in properties and \
not self._getcontext().cfgimpl_get_values()._isempty( not self._getcontext().cfgimpl_get_values()._isempty(
opt_or_descr, value, index=index): opt_or_descr, value, index=index):
properties.remove('mandatory') properties.remove('mandatory')
elif opt_or_descr.impl_is_multi() and \ elif opt_or_descr.impl_is_multi() and \
not is_write and 'empty' in forced_properties and \ 'empty' in setting_properties and \
not opt_or_descr.impl_is_master_slaves('slave') and \ not opt_or_descr.impl_is_master_slaves('slave') and \
self._getcontext().cfgimpl_get_values()._isempty( self._getcontext().cfgimpl_get_values()._isempty(
opt_or_descr, value, force_allow_empty_list=True): opt_or_descr, value, force_allow_empty_list=True):
properties.add('mandatory') properties.add('mandatory')
if is_write and 'everything_frozen' in forced_properties: # should return 'frozen' only when tried to modify a value
if check_frozen and 'everything_frozen' in setting_properties:
properties.add('frozen') properties.add('frozen')
elif 'frozen' in properties and not is_write: elif 'frozen' in properties and not check_frozen:
properties.remove('frozen') properties.remove('frozen')
# at this point an option should not remain in properties # at this point an option should not remain in properties
if properties != frozenset(): if properties != frozenset():
@ -504,7 +494,7 @@ class Settings(object):
opt_or_descr.impl_getname()), opt_or_descr.impl_getname()),
props) props)
else: else:
if opt_or_descr.impl_is_optiondescription(): if is_descr:
opt_type = 'optiondescription' opt_type = 'optiondescription'
else: else:
opt_type = 'option' opt_type = 'option'

View File

@ -151,29 +151,27 @@ class Values(object):
"""overrides the builtins `del()` instructions""" """overrides the builtins `del()` instructions"""
self.reset(opt) self.reset(opt)
def reset(self, opt, path=None, validate=True): def reset(self, opt, path=None, validate=True, _setting_properties=None):
if path is None:
path = opt.impl_getpath(self._getcontext())
context = self._getcontext() context = self._getcontext()
if validate: setting = context.cfgimpl_get_settings()
context.cfgimpl_get_settings().validate_properties(opt, False, if path is None:
True, path) path = opt.impl_getpath(context)
if _setting_properties is None:
_setting_properties = setting._getproperties(read_write=False)
hasvalue = self._contains(path) hasvalue = self._contains(path)
setting = context.cfgimpl_get_settings() if validate and hasvalue and 'validator' in _setting_properties:
setting_properties = setting._getproperties(read_write=False)
if 'validator' in setting_properties and validate and hasvalue:
fake_context = context._gen_fake_values() fake_context = context._gen_fake_values()
fake_value = fake_context.cfgimpl_get_values() fake_value = fake_context.cfgimpl_get_values()
fake_value.reset(opt, path, validate=False) fake_value.reset(opt, path, validate=False)
opt.impl_validate(getattr(fake_context, path), fake_value._get_cached_value(opt, path,
fake_context, 'validator' in setting_properties) setting_properties=_setting_properties,
context.cfgimpl_reset_cache() check_frozen=True)
if opt.impl_is_master_slaves('master'): if opt.impl_is_master_slaves('master'):
opt.impl_get_master_slaves().reset(opt, self) opt.impl_get_master_slaves().reset(opt, self, _setting_properties)
if hasvalue: if hasvalue:
self._p_.resetvalue(path) self._p_.resetvalue(path)
context.cfgimpl_reset_cache()
def _isempty(self, opt, value, force_allow_empty_list=False, index=None): def _isempty(self, opt, value, force_allow_empty_list=False, index=None):
"convenience method to know if an option is empty" "convenience method to know if an option is empty"
@ -212,18 +210,19 @@ class Values(object):
validate_properties=True, validate_properties=True,
setting_properties=undefined, self_properties=undefined, setting_properties=undefined, self_properties=undefined,
index=None, from_masterslave=False, with_meta=True, index=None, from_masterslave=False, with_meta=True,
masterlen=undefined): masterlen=undefined, check_frozen=False):
context = self._getcontext() context = self._getcontext()
settings = context.cfgimpl_get_settings()
if path is None: if path is None:
path = opt.impl_getpath(context) path = opt.impl_getpath(context)
ntime = None ntime = None
if setting_properties is undefined: if setting_properties is undefined:
setting_properties = context.cfgimpl_get_settings( setting_properties = settings._getproperties(read_write=False)
)._getproperties(read_write=False)
if self_properties is undefined: if self_properties is undefined:
self_properties = context.cfgimpl_get_settings()._getproperties( self_properties = settings._getproperties(opt, path,
opt, path, read_write=False, read_write=False,
setting_properties=setting_properties, index=index) setting_properties=setting_properties,
index=index)
if 'cache' in setting_properties and self._p_.hascache(path, index): if 'cache' in setting_properties and self._p_.hascache(path, index):
if 'expire' in setting_properties: if 'expire' in setting_properties:
ntime = int(time()) ntime = int(time())
@ -232,8 +231,8 @@ class Values(object):
if opt.impl_is_multi() and not isinstance(value, Multi) and index is None: if opt.impl_is_multi() and not isinstance(value, Multi) and index is None:
value = Multi(value, self.context, opt, path) value = Multi(value, self.context, opt, path)
if not trusted_cached_properties: if not trusted_cached_properties:
# revalidate properties (because not default properties) # revalidate properties (because of not default properties)
context.cfgimpl_get_settings().validate_properties(opt, False, False, value=value, settings.validate_properties(opt, False, False, value=value,
path=path, path=path,
force_permissive=force_permissive, force_permissive=force_permissive,
setting_properties=setting_properties, setting_properties=setting_properties,
@ -257,10 +256,12 @@ class Values(object):
self_properties=self_properties, self_properties=self_properties,
with_meta=with_meta, with_meta=with_meta,
masterlen=masterlen, masterlen=masterlen,
index=index) index=index,
check_frozen=check_frozen)
# cache doesn't work with SubMulti yet # cache doesn't work with SubMulti yet
if not isinstance(val, SubMulti) and 'cache' in setting_properties and validate and validate_properties \ if not isinstance(val, SubMulti) and 'cache' in setting_properties and \
and force_permissive is False and trusted_cached_properties is True: validate and validate_properties and force_permissive is False \
and trusted_cached_properties is True:
if 'expire' in setting_properties: if 'expire' in setting_properties:
if ntime is None: if ntime is None:
ntime = int(time()) ntime = int(time())
@ -272,7 +273,8 @@ class Values(object):
validate_properties, validate_properties,
index=None, submulti_index=undefined, index=None, submulti_index=undefined,
with_meta=True, setting_properties=undefined, with_meta=True, setting_properties=undefined,
self_properties=undefined, masterlen=undefined): self_properties=undefined, masterlen=undefined,
check_frozen=False):
"""same has getitem but don't touch the cache """same has getitem but don't touch the cache
index is None for slave value, if value returned is not a list, just return [] index is None for slave value, if value returned is not a list, just return []
""" """
@ -337,7 +339,7 @@ class Values(object):
item = list(value) item = list(value)
else: else:
item = value item = value
self.setitem(opt, item, path, is_write=False, self.setitem(opt, item, path, check_frozen=False,
force_permissive=force_permissive) force_permissive=force_permissive)
if validate_properties: if validate_properties:
if config_error is not None: if config_error is not None:
@ -346,7 +348,7 @@ class Values(object):
val_props = undefined val_props = undefined
else: else:
val_props = value val_props = value
setting.validate_properties(opt, False, False, value=val_props, setting.validate_properties(opt, False, check_frozen, value=val_props,
path=path, path=path,
force_permissive=force_permissive, force_permissive=force_permissive,
setting_properties=setting_properties, setting_properties=setting_properties,
@ -360,8 +362,8 @@ class Values(object):
raise ConfigError(_('you should only set value with config')) raise ConfigError(_('you should only set value with config'))
def setitem(self, opt, value, path, force_permissive=False, def setitem(self, opt, value, path, force_permissive=False,
is_write=True): check_frozen=True):
# is_write is, for example, used with "force_store_value" # check_frozen is, for example, used with "force_store_value"
# user didn't change value, so not write # user didn't change value, so not write
# valid opt # valid opt
context = self._getcontext() context = self._getcontext()
@ -370,32 +372,26 @@ class Values(object):
fake_context = context._gen_fake_values() fake_context = context._gen_fake_values()
fake_context.cfgimpl_get_values()._setitem(opt, value, path, fake_context.cfgimpl_get_values()._setitem(opt, value, path,
force_permissive, force_permissive,
is_write, check_frozen,
setting_properties) setting_properties)
opt.impl_validate(value, fake_context) opt.impl_validate(value, fake_context)
self._setitem(opt, value, path, force_permissive, is_write, self._setitem(opt, value, path, force_permissive, check_frozen,
setting_properties, validate_properties=False) setting_properties, validate_properties=False)
def _setitem(self, opt, value, path, force_permissive, is_write, def _setitem(self, opt, value, path, force_permissive, check_frozen,
setting_properties, validate_properties=True): setting_properties, validate_properties=True):
if opt.impl_is_master_slaves(): if opt.impl_is_master_slaves():
opt.impl_get_master_slaves().setitem(self, opt, value, path) opt.impl_get_master_slaves().setitem(self, opt, value, path)
self._setvalue(opt, path, value, force_permissive=force_permissive, self._setvalue(opt, path, value, force_permissive=force_permissive,
is_write=is_write, check_frozen=check_frozen,
setting_properties=setting_properties, setting_properties=setting_properties,
validate_properties=validate_properties) validate_properties=validate_properties)
def _setvalue(self, opt, path, value, force_permissive=False, def _setvalue(self, opt, path, value, force_permissive=False,
is_write=True, validate_properties=True, check_frozen=True, validate_properties=True,
setting_properties=undefined, index=None): setting_properties=undefined, index=None):
context = self._getcontext() context = self._getcontext()
context.cfgimpl_reset_cache() context.cfgimpl_reset_cache()
if validate_properties:
setting = context.cfgimpl_get_settings()
setting.validate_properties(opt, False, is_write,
value=value, path=path,
force_permissive=force_permissive,
setting_properties=setting_properties)
if isinstance(value, Multi): if isinstance(value, Multi):
value = list(value) value = list(value)
if opt.impl_is_submulti(): if opt.impl_is_submulti():
@ -412,6 +408,12 @@ class Values(object):
self._p_.setvalue(path, val, owner, idx) self._p_.setvalue(path, val, owner, idx)
else: else:
self._p_.setvalue(path, value, owner, index) self._p_.setvalue(path, value, owner, index)
if validate_properties:
setting = context.cfgimpl_get_settings()
setting.validate_properties(opt, False, check_frozen,
value=value, path=path,
force_permissive=force_permissive,
setting_properties=setting_properties)
def _is_meta(self, opt, path): def _is_meta(self, opt, path):
context = self._getcontext() context = self._getcontext()