refactor and better test in api
This commit is contained in:
parent
a8d022b67f
commit
007a22ca94
|
@ -210,8 +210,8 @@ def test_callback_submulti_list_list():
|
|||
|
||||
|
||||
def test_values_with_master_and_slaves_submulti():
|
||||
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
|
||||
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=submulti)
|
||||
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip reseau autorise", multi=True)
|
||||
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-reseau", multi=submulti)
|
||||
interface1 = MasterSlaves('f_ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
|
||||
conf = OptionDescription('conf', '', [interface1])
|
||||
cfg = Config(conf)
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
"""
|
||||
import pytest
|
||||
from py.test import raises
|
||||
import weakref
|
||||
from .autopath import do_autopath
|
||||
do_autopath()
|
||||
from tiramisu import Config, StrOption, OptionDescription, MasterSlaves, DynOptionDescription, \
|
||||
|
@ -55,7 +56,10 @@ def autocheck_owner_without_value(api, path, **kwargs):
|
|||
isslave = False
|
||||
# check if owner is a string "default"
|
||||
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
|
||||
if not isslave:
|
||||
assert api.option(path).owner.get() == 'default'
|
||||
else:
|
||||
assert api.option(path, 0).owner.get() == 'default'
|
||||
else:
|
||||
if not isslave:
|
||||
raises(PropertiesOptionError, "api.option(path).owner.get()")
|
||||
|
@ -76,7 +80,10 @@ def autocheck_owner_without_value(api, path, **kwargs):
|
|||
# check if default owner
|
||||
raises(APIError, "api.unrestraint.option(path).owner.isdefault()")
|
||||
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
|
||||
if not isslave:
|
||||
assert api.option(path).owner.isdefault()
|
||||
else:
|
||||
assert api.option(path, 0).owner.isdefault()
|
||||
else:
|
||||
raises(PropertiesOptionError, "api.option(path).owner.isdefault()")
|
||||
if not kwargs.get('propertyerror', False):
|
||||
|
@ -141,7 +148,6 @@ def autocheck_value(api, path, **kwargs):
|
|||
api.option(path).value.set([first_value[0]])
|
||||
elif isslave:
|
||||
api.option(path, 0).value.set(first_value[0])
|
||||
raise Exception('pouet')
|
||||
else:
|
||||
api.option(path).value.set(first_value)
|
||||
else:
|
||||
|
@ -321,6 +327,14 @@ def autocheck_value2(*args, **kwargs):
|
|||
autocheck_value(*args, **kwargs)
|
||||
|
||||
|
||||
@autocheck
|
||||
def autocheck_display(api, path, **kwargs):
|
||||
"""re set value
|
||||
"""
|
||||
#FIXME utile ?
|
||||
print(api.config)
|
||||
|
||||
|
||||
@autocheck
|
||||
def autocheck_property(api, path, **kwargs):
|
||||
"""get property from path
|
||||
|
@ -756,6 +770,7 @@ def check_all(api, path, multi, **kwargs):
|
|||
text = u' {} launch tests for {}'.format(ICON, path)
|
||||
if multi:
|
||||
text += u' as a multi'
|
||||
text += u', kwargs: {}'.format(kwargs)
|
||||
print(text)
|
||||
for func in autocheck_registers:
|
||||
if DISPLAY:
|
||||
|
@ -764,6 +779,7 @@ def check_all(api, path, multi, **kwargs):
|
|||
|
||||
|
||||
def make_api(options, multi):
|
||||
weakrefs = []
|
||||
def make_option(path, option_infos):
|
||||
#FIXME
|
||||
option_type = 'str'
|
||||
|
@ -779,7 +795,9 @@ def make_api(options, multi):
|
|||
if multi:
|
||||
kwargs['multi'] = True
|
||||
tiramisu_option = OPTIONS_TYPE[option_type]['option']
|
||||
return tiramisu_option(*args, **kwargs)
|
||||
obj = tiramisu_option(*args, **kwargs)
|
||||
weakrefs.append(weakref.ref(obj))
|
||||
return obj
|
||||
|
||||
def make_optiondescriptions(path, collected):
|
||||
infos = collected.get('properties', {})
|
||||
|
@ -809,7 +827,9 @@ def make_api(options, multi):
|
|||
options.append(option)
|
||||
if properties != []:
|
||||
kwargs['properties'] = tuple(properties)
|
||||
return optiondescription(path, "{}'s optiondescription".format(path), options, **kwargs)
|
||||
obj = optiondescription(path, "{}'s optiondescription".format(path), options, **kwargs)
|
||||
weakrefs.append(weakref.ref(obj))
|
||||
return obj
|
||||
|
||||
collect_options = {}
|
||||
for path, option in options.items():
|
||||
|
@ -826,16 +846,20 @@ def make_api(options, multi):
|
|||
|
||||
rootod = make_optiondescriptions('root', collect_options)
|
||||
if rootod is None:
|
||||
return
|
||||
cfg = Config(rootod)
|
||||
return getapi(cfg)
|
||||
return None, None
|
||||
cfg = Config(rootod, session_id='conftest')
|
||||
weakrefs.append(weakref.ref(cfg))
|
||||
api = getapi(cfg)
|
||||
weakrefs.append(weakref.ref(api))
|
||||
return api, weakrefs
|
||||
|
||||
|
||||
DICT_PATHS = [
|
||||
#test a config without optiondescription
|
||||
OrderedDict([('first', {}),
|
||||
('second', {'second': {'disabled': True}}),
|
||||
('third', {'third': {'hidden': True}})]),
|
||||
('third', {'third': {'hidden': True}})
|
||||
]),
|
||||
#test a config with an optiondescription
|
||||
OrderedDict([('subod.first', {}),
|
||||
('subod.second', {'second': {'disabled': True}}),
|
||||
|
@ -864,8 +888,22 @@ DICT_PATHS = [
|
|||
('subodval2.thirdval2', None)]),
|
||||
#test a config with dynoption subdir
|
||||
OrderedDict([('subod.subsubod.first', {'subsubod': {'dyn': True}}),
|
||||
('subod.subsubod.second', {'second': {'disabled': True}}),
|
||||
('subod.subsubod.third', {'third': {'hidden': True}}),
|
||||
('subod.subsubod.second', {'subsubod': {'dyn': True}, 'second': {'disabled': True}}),
|
||||
('subod.subsubod.third', {'subsubod': {'dyn': True}, 'third': {'hidden': True}}),
|
||||
('subod.subsubodval1.firstval1', None),
|
||||
('subod.subsubodval1.secondval1', None),
|
||||
('subod.subsubodval1.thirdval1', None),
|
||||
('subod.subsubodval2.firstval2', None),
|
||||
('subod.subsubodval2.secondval2', None),
|
||||
('subod.subsubodval2.thirdval2', None)]),
|
||||
#test a config with hidden subsubod
|
||||
OrderedDict([('subod.subsubod.first', {'subsubod': {'hidden': True}}),
|
||||
('subod.subsubod.second', {'subsubod': {'hidden': True}}),
|
||||
('subod.subsubod.third', {'subsubod': {'hidden': True}})]),
|
||||
#test a config with hidden dyn subsubod
|
||||
OrderedDict([('subod.subsubod.first', {'subsubod': {'dyn': True, 'hidden': True}}),
|
||||
('subod.subsubod.second', {'subsubod': {'dyn': True, 'hidden': True}}),
|
||||
('subod.subsubod.third', {'subsubod': {'dyn': True, 'hidden': True}}),
|
||||
('subod.subsubodval1.firstval1', None),
|
||||
('subod.subsubodval1.secondval1', None),
|
||||
('subod.subsubodval1.thirdval1', None),
|
||||
|
@ -883,63 +921,40 @@ def paths(request):
|
|||
|
||||
|
||||
def test_options(paths):
|
||||
def get_kwargs_option(options, kwargs, od=False):
|
||||
if options.get('hidden', False) is True:
|
||||
kwargs['permissive'] = True
|
||||
if not od:
|
||||
kwargs.setdefault('extra_properties', []).append('hidden')
|
||||
if options.get('disabled', False) is True:
|
||||
kwargs['propertyerror'] = True
|
||||
if not od:
|
||||
kwargs.setdefault('extra_properties', []).append('disabled')
|
||||
|
||||
def get_kwargs(path):
|
||||
kwargs = {}
|
||||
spath = path.split('.')
|
||||
get_kwargs_option(paths[path].get(spath[-1], {}), kwargs)
|
||||
if len(spath) > 1:
|
||||
get_kwargs_option(paths[path].get(spath[-2], {}), kwargs, od=True)
|
||||
return kwargs
|
||||
|
||||
lpaths = list(paths.keys())
|
||||
for multi in (False, True):
|
||||
api = make_api(paths, multi)
|
||||
api, weakrefs = make_api(paths, multi)
|
||||
if api is None:
|
||||
continue
|
||||
if len(lpaths) == 9:
|
||||
check_all(api, lpaths[3], multi)
|
||||
check_all(api, lpaths[4], multi, propertyerror=True, extra_properties=['disabled'])
|
||||
check_all(api, lpaths[5], multi, permissive=True, extra_properties=['hidden'])
|
||||
check_all(api, lpaths[6], multi)
|
||||
check_all(api, lpaths[7], multi, propertyerror=True, extra_properties=['disabled'])
|
||||
check_all(api, lpaths[8], multi, permissive=True, extra_properties=['hidden'])
|
||||
check_all(api, lpaths[3], multi, **get_kwargs(lpaths[0]))
|
||||
check_all(api, lpaths[4], multi, **get_kwargs(lpaths[1]))
|
||||
check_all(api, lpaths[5], multi, **get_kwargs(lpaths[2]))
|
||||
check_all(api, lpaths[6], multi, **get_kwargs(lpaths[0]))
|
||||
check_all(api, lpaths[7], multi, **get_kwargs(lpaths[1]))
|
||||
check_all(api, lpaths[8], multi, **get_kwargs(lpaths[2]))
|
||||
else:
|
||||
check_all(api, lpaths[0], multi)
|
||||
check_all(api, lpaths[1], multi, propertyerror=True, extra_properties=['disabled'])
|
||||
check_all(api, lpaths[2], multi, permissive=True, extra_properties=['hidden'])
|
||||
|
||||
|
||||
DICT_PATHS2 = [
|
||||
OrderedDict([('subod.subsubod.first', {'subsubod': {'hidden': True}}),
|
||||
('subod.subsubod.second', {}),
|
||||
('subod.subsubod.third', {})]),
|
||||
OrderedDict([('subod.subsubod.first', {'subsubod': {'dyn': True, 'hidden': True}}),
|
||||
('subod.subsubod.second', {}),
|
||||
('subod.subsubod.third', {}),
|
||||
('subod.subsubodval1.firstval1', None),
|
||||
('subod.subsubodval1.secondval1', None),
|
||||
('subod.subsubodval1.thirdval1', None),
|
||||
('subod.subsubodval2.firstval2', None),
|
||||
('subod.subsubodval2.secondval2', None),
|
||||
('subod.subsubodval2.thirdval2', None)])
|
||||
]
|
||||
|
||||
|
||||
@pytest.fixture(scope="function", params=DICT_PATHS2)
|
||||
def paths2(request):
|
||||
if DISPLAY:
|
||||
print(u'\n{} {}: {}'.format(ICON, request.function.__name__, request.param))
|
||||
return request.param
|
||||
|
||||
|
||||
def test_tree_od_permissive(paths2):
|
||||
"""permissive when optiondescription is hidden
|
||||
"""
|
||||
lpaths = list(paths2.keys())
|
||||
for multi in (False, True):
|
||||
api = make_api(paths2, multi)
|
||||
if api is None:
|
||||
continue
|
||||
if len(lpaths) == 9:
|
||||
check_all(api, lpaths[3], multi, permissive=True)
|
||||
check_all(api, lpaths[4], multi, permissive=True)
|
||||
check_all(api, lpaths[5], multi, permissive=True)
|
||||
check_all(api, lpaths[6], multi, permissive=True)
|
||||
check_all(api, lpaths[7], multi, permissive=True)
|
||||
check_all(api, lpaths[8], multi, permissive=True)
|
||||
else:
|
||||
check_all(api, lpaths[0], multi, permissive=True)
|
||||
check_all(api, lpaths[1], multi, permissive=True)
|
||||
check_all(api, lpaths[2], multi, permissive=True)
|
||||
check_all(api, lpaths[0], multi, **get_kwargs(lpaths[0]))
|
||||
check_all(api, lpaths[1], multi, **get_kwargs(lpaths[1]))
|
||||
check_all(api, lpaths[2], multi, **get_kwargs(lpaths[2]))
|
||||
del(api)
|
||||
for wr in weakrefs:
|
||||
assert wr() is None
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ____________________________________________________________
|
||||
from inspect import ismethod, getdoc
|
||||
from .error import APIError
|
||||
from .error import APIError, PropertiesOptionError
|
||||
from .i18n import _
|
||||
from .setting import owners, undefined
|
||||
try:
|
||||
|
@ -377,7 +377,7 @@ class TiramisuAPI(object):
|
|||
self.force_permissive = force_permissive
|
||||
self.force_unrestraint = force_unrestraint
|
||||
settings = self.config.cfgimpl_get_settings()
|
||||
#FIXME ?
|
||||
# #FIXME ?
|
||||
self.config.read_write()
|
||||
settings.setpermissive(('hidden',))
|
||||
#/FIXME ?
|
||||
|
@ -386,8 +386,12 @@ class TiramisuAPI(object):
|
|||
validate = not self.force_unrestraint
|
||||
settings = self.config.cfgimpl_get_settings()
|
||||
setting_properties = settings.get_global_properties()
|
||||
if validate:
|
||||
s_properties = setting_properties
|
||||
else:
|
||||
s_properties = None
|
||||
opt = self.config.unwrap_from_path(path,
|
||||
setting_properties=setting_properties,
|
||||
setting_properties=s_properties,
|
||||
validate=validate,
|
||||
validate_properties=validate,
|
||||
force_permissive=self.force_permissive,
|
||||
|
|
|
@ -87,18 +87,7 @@ class SubConfig(object):
|
|||
validate=validate,
|
||||
force_permissive=force_permissive)
|
||||
|
||||
def cfgimpl_reset_cache(self,
|
||||
only_expired=False,
|
||||
only=('values', 'properties', 'permissives', 'settings'),
|
||||
opt=None,
|
||||
path=None,
|
||||
resetted_opts=None):
|
||||
"""reset all settings in cache
|
||||
|
||||
:param only_expired: if True reset only expired cached values
|
||||
:type only_expired: boolean
|
||||
"""
|
||||
def reset_one_option_cache(opt, resetted_opts):
|
||||
def reset_one_option_cache(self, values, settings, resetted_opts, opt, only):
|
||||
if 'values' in only:
|
||||
tresetted_opts = copy(resetted_opts)
|
||||
opt.reset_cache(opt, values, 'values', tresetted_opts)
|
||||
|
@ -117,8 +106,20 @@ class SubConfig(object):
|
|||
for option in opt._get_dependencies(self):
|
||||
if option in resetted_opts:
|
||||
continue
|
||||
reset_one_option_cache(option, resetted_opts)
|
||||
self.reset_one_option_cache(values, settings, resetted_opts, option(), only)
|
||||
del(option)
|
||||
|
||||
def cfgimpl_reset_cache(self,
|
||||
only_expired=False,
|
||||
only=('values', 'properties', 'permissives', 'settings'),
|
||||
opt=None,
|
||||
path=None,
|
||||
resetted_opts=None):
|
||||
"""reset all settings in cache
|
||||
|
||||
:param only_expired: if True reset only expired cached values
|
||||
:type only_expired: boolean
|
||||
"""
|
||||
|
||||
def reset_expired_cache():
|
||||
# reset cache for expired cache value ony
|
||||
|
@ -153,7 +154,11 @@ class SubConfig(object):
|
|||
|
||||
if not None in (opt, path):
|
||||
if opt not in resetted_opts:
|
||||
reset_one_option_cache(opt, resetted_opts)
|
||||
self.reset_one_option_cache(values,
|
||||
settings,
|
||||
resetted_opts,
|
||||
opt,
|
||||
only)
|
||||
|
||||
elif only_expired:
|
||||
reset_expired_cache()
|
||||
|
@ -164,15 +169,13 @@ class SubConfig(object):
|
|||
path,
|
||||
setting_properties,
|
||||
validate_properties=True,
|
||||
force_permissive=False,
|
||||
returns_raise=False):
|
||||
force_permissive=False):
|
||||
""":returns: tuple (config, name)"""
|
||||
path = path.split('.')
|
||||
for step in path[:-1]:
|
||||
self = self.getattr(step,
|
||||
force_permissive=force_permissive,
|
||||
validate_properties=validate_properties,
|
||||
returns_raise=returns_raise,
|
||||
setting_properties=setting_properties)
|
||||
if isinstance(self, Exception):
|
||||
return self, None
|
||||
|
@ -182,13 +185,16 @@ class SubConfig(object):
|
|||
def __iter__(self, force_permissive=False):
|
||||
"""Pythonesque way of parsing group's ordered options.
|
||||
iteration only on Options (not OptionDescriptions)"""
|
||||
setting_properties = self.cfgimpl_get_context().cfgimpl_get_settings(
|
||||
)._getproperties(read_write=True)
|
||||
for child in self.cfgimpl_get_description()._impl_getchildren(
|
||||
context=self._cfgimpl_get_context()):
|
||||
if not child.impl_is_optiondescription():
|
||||
try:
|
||||
name = child.impl_getname()
|
||||
yield name, self.getattr(name,
|
||||
force_permissive=force_permissive)
|
||||
force_permissive=force_permissive,
|
||||
setting_properties=setting_properties)
|
||||
except GeneratorExit: # pragma: optional cover
|
||||
if sys.version_info[0] < 3:
|
||||
raise StopIteration
|
||||
|
@ -224,15 +230,19 @@ class SubConfig(object):
|
|||
if group_type is not None and not isinstance(group_type,
|
||||
groups.GroupType): # pragma: optional cover
|
||||
raise TypeError(_("unknown group_type: {0}").format(group_type))
|
||||
context = self._cfgimpl_get_context()
|
||||
setting_properties = context.cfgimpl_get_settings()._getproperties(read_write=True)
|
||||
for child in self.cfgimpl_get_description()._impl_getchildren(
|
||||
context=self._cfgimpl_get_context()):
|
||||
context=context):
|
||||
if child.impl_is_optiondescription():
|
||||
try:
|
||||
if group_type is None or (group_type is not None and
|
||||
child.impl_get_group_type()
|
||||
== group_type):
|
||||
name = child.impl_getname()
|
||||
yield name, self.getattr(name, force_permissive=force_permissive)
|
||||
yield name, self.getattr(name,
|
||||
force_permissive=force_permissive,
|
||||
setting_properties=setting_properties)
|
||||
except GeneratorExit: # pragma: optional cover
|
||||
if sys.version_info[0] < 3:
|
||||
raise StopIteration
|
||||
|
@ -391,7 +401,7 @@ class SubConfig(object):
|
|||
raise ret
|
||||
|
||||
def __getattr__(self, name):
|
||||
setting_properties = self.cfgimpl_get_context().cfgimpl_get_settings().getcontextproperties()
|
||||
setting_properties = self.cfgimpl_get_context().cfgimpl_get_settings().get_global_properties()
|
||||
return self.getattr(name, setting_properties)
|
||||
|
||||
def _get_subpath(self, name):
|
||||
|
@ -408,7 +418,6 @@ class SubConfig(object):
|
|||
validate=True,
|
||||
validate_properties=True,
|
||||
index=None,
|
||||
returns_raise=False,
|
||||
returns_option=False):
|
||||
"""
|
||||
attribute notation mechanism for accessing the value of an option
|
||||
|
@ -423,7 +432,6 @@ class SubConfig(object):
|
|||
homeconfig, name = self.cfgimpl_get_home_by_path(name,
|
||||
force_permissive=force_permissive,
|
||||
validate_properties=validate_properties,
|
||||
returns_raise=returns_raise,
|
||||
setting_properties=setting_properties)
|
||||
if isinstance(homeconfig, Exception):
|
||||
cfg = homeconfig
|
||||
|
@ -433,8 +441,7 @@ class SubConfig(object):
|
|||
validate=validate,
|
||||
validate_properties=validate_properties,
|
||||
setting_properties=setting_properties,
|
||||
index=index,
|
||||
returns_raise=returns_raise)
|
||||
index=index)
|
||||
else:
|
||||
option = self.cfgimpl_get_description().__getattr__(name,
|
||||
context=context)
|
||||
|
@ -454,8 +461,7 @@ class SubConfig(object):
|
|||
validate_properties=validate_properties,
|
||||
force_permissive=force_permissive,
|
||||
setting_properties=setting_properties,
|
||||
index=index,
|
||||
returns_raise=True)
|
||||
index=index)
|
||||
elif option.impl_is_optiondescription():
|
||||
if setting_properties:
|
||||
props = self.cfgimpl_get_settings().validate_properties(option,
|
||||
|
@ -464,11 +470,6 @@ class SubConfig(object):
|
|||
path=subpath,
|
||||
force_permissive=force_permissive,
|
||||
setting_properties=setting_properties)
|
||||
if props:
|
||||
if returns_raise:
|
||||
return props
|
||||
else:
|
||||
raise props
|
||||
if returns_option is True:
|
||||
return option
|
||||
return SubConfig(option,
|
||||
|
@ -482,11 +483,6 @@ class SubConfig(object):
|
|||
ret = self.cfgimpl_get_description().impl_validate(context,
|
||||
force_permissive,
|
||||
setting_properties)
|
||||
if ret:
|
||||
if returns_raise:
|
||||
return ret
|
||||
else:
|
||||
raise ret
|
||||
cfg = self.cfgimpl_get_values().get_cached_value(option,
|
||||
path=subpath,
|
||||
validate=validate,
|
||||
|
@ -494,8 +490,6 @@ class SubConfig(object):
|
|||
force_permissive=force_permissive,
|
||||
setting_properties=setting_properties,
|
||||
index=index)
|
||||
if not returns_raise and isinstance(cfg, Exception):
|
||||
raise cfg
|
||||
if returns_option is True:
|
||||
return option
|
||||
else:
|
||||
|
@ -549,14 +543,12 @@ class SubConfig(object):
|
|||
def _filter_by_value():
|
||||
if byvalue is undefined:
|
||||
return True
|
||||
try:
|
||||
value = self.getattr(path, force_permissive=force_permissive,
|
||||
setting_properties=setting_properties,
|
||||
returns_raise=True)
|
||||
if isinstance(value, Exception):
|
||||
if isinstance(value, PropertiesOptionError):
|
||||
setting_properties=setting_properties)
|
||||
except PropertiesOptionError:
|
||||
return False
|
||||
raise value # pragma: no cover
|
||||
elif isinstance(value, list):
|
||||
if isinstance(value, list):
|
||||
return byvalue in value
|
||||
else:
|
||||
return value == byvalue
|
||||
|
@ -581,15 +573,12 @@ class SubConfig(object):
|
|||
continue
|
||||
#remove option with propertyerror, ...
|
||||
if byvalue is undefined and check_properties:
|
||||
try:
|
||||
value = self.getattr(path,
|
||||
force_permissive=force_permissive,
|
||||
setting_properties=setting_properties,
|
||||
returns_raise=True)
|
||||
if isinstance(value, Exception):
|
||||
if isinstance(value, PropertiesOptionError):
|
||||
setting_properties=setting_properties)
|
||||
except PropertiesOptionError:
|
||||
continue
|
||||
else:
|
||||
raise value # pragma: no cover
|
||||
if type_ == 'value':
|
||||
retval = value
|
||||
elif type_ == 'path':
|
||||
|
@ -707,13 +696,12 @@ class SubConfig(object):
|
|||
|
||||
def _make_sub_dict(self, opt, path, pathsvalues, _currpath, flatten,
|
||||
setting_properties, force_permissive=False, fullpath=False):
|
||||
try:
|
||||
value = self.getattr(path,
|
||||
force_permissive=force_permissive,
|
||||
setting_properties=setting_properties,
|
||||
returns_raise=True)
|
||||
if isinstance(value, Exception):
|
||||
if not isinstance(value, PropertiesOptionError): # pragma: no cover
|
||||
raise value
|
||||
setting_properties=setting_properties)
|
||||
except PropertiesOptionError as err:
|
||||
pass
|
||||
else:
|
||||
if opt.impl_is_optiondescription():
|
||||
pathsvalues += value.make_dict(flatten,
|
||||
|
@ -792,10 +780,8 @@ class _CommonConfig(SubConfig):
|
|||
force_permissive=force_permissive,
|
||||
validate_properties=validate_properties,
|
||||
setting_properties=setting_properties)
|
||||
if not validate_properties:
|
||||
return self.cfgimpl_get_description().__getattr__(path,
|
||||
context=self._cfgimpl_get_context())
|
||||
else:
|
||||
if isinstance(self, Exception):
|
||||
return self
|
||||
option = self.cfgimpl_get_description().__getattr__(path,
|
||||
context=self._cfgimpl_get_context())
|
||||
if not validate_properties:
|
||||
|
@ -1037,7 +1023,6 @@ class GroupConfig(_CommonConfig):
|
|||
force_permissive=False,
|
||||
validate=True,
|
||||
index=None,
|
||||
returns_raise=False,
|
||||
validate_properties=True,
|
||||
returns_option=False):
|
||||
for child in self._impl_children:
|
||||
|
@ -1047,7 +1032,6 @@ class GroupConfig(_CommonConfig):
|
|||
validate,
|
||||
index=index,
|
||||
setting_properties=setting_properties,
|
||||
returns_raise=returns_raise,
|
||||
validate_properties=validate_properties,
|
||||
returns_option=False)
|
||||
|
||||
|
@ -1117,8 +1101,7 @@ class MetaConfig(GroupConfig):
|
|||
continue
|
||||
if force_dont_change_value:
|
||||
child_value = child.getattr(path,
|
||||
setting_properties=setting_properties,
|
||||
returns_raise=True)
|
||||
setting_properties=setting_properties)
|
||||
if isinstance(child_value, Exception):
|
||||
ret.append(child_value)
|
||||
elif value != child_value:
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
import re
|
||||
from types import FunctionType
|
||||
import sys
|
||||
import weakref
|
||||
|
||||
from ..i18n import _
|
||||
from ..setting import undefined
|
||||
|
@ -164,7 +165,7 @@ class Base(object):
|
|||
_setattr(self, '_calc_properties', calc_properties)
|
||||
if requires is not undefined:
|
||||
_setattr(self, '_requires', requires)
|
||||
if properties is not undefined:
|
||||
if properties:
|
||||
_setattr(self, '_properties', properties)
|
||||
|
||||
def _build_validator_params(self, validator, validator_params):
|
||||
|
@ -213,14 +214,15 @@ class Base(object):
|
|||
def _get_dependencies(self, context):
|
||||
if context:
|
||||
od = context.cfgimpl_get_description()
|
||||
ret = set(getattr(self, '_dependencies', STATIC_TUPLE))
|
||||
if context and hasattr(od, '_dependencies'):
|
||||
return set(od._dependencies) | set(getattr(self, '_dependencies', STATIC_TUPLE))
|
||||
return set(od._dependencies) | ret
|
||||
else:
|
||||
return getattr(self, '_dependencies', STATIC_TUPLE)
|
||||
return ret
|
||||
|
||||
def _add_dependency(self, option):
|
||||
options = set(self._get_dependencies(None))
|
||||
options.add(option)
|
||||
options = self._get_dependencies(None)
|
||||
options.add(weakref.ref(option))
|
||||
self._dependencies = tuple(options)
|
||||
|
||||
def impl_set_callback(self, callback, callback_params=None, _init=False):
|
||||
|
@ -260,7 +262,7 @@ class Base(object):
|
|||
return not isinstance(getattr(self, '_informations', dict()), dict)
|
||||
|
||||
def impl_getproperties(self):
|
||||
return self._properties
|
||||
return getattr(self, '_properties', STATIC_TUPLE)
|
||||
|
||||
def _set_readonly(self):
|
||||
if not self.impl_is_readonly():
|
||||
|
@ -277,7 +279,7 @@ class Base(object):
|
|||
_setattr(self, '_extra', tuple([tuple(extra.keys()), tuple(extra.values())]))
|
||||
|
||||
def _impl_setsubdyn(self, subdyn):
|
||||
self._subdyn = subdyn
|
||||
self._subdyn = weakref.ref(subdyn)
|
||||
|
||||
def impl_getrequires(self):
|
||||
return getattr(self, '_requires', STATIC_TUPLE)
|
||||
|
@ -599,7 +601,7 @@ class SymLinkOption(OnlyOption):
|
|||
return True
|
||||
|
||||
def impl_getproperties(self):
|
||||
return self._impl_getopt()._properties
|
||||
return self._impl_getopt().impl_getproperties()
|
||||
|
||||
def impl_get_callback(self):
|
||||
return self._impl_getopt().impl_get_callback()
|
||||
|
|
|
@ -194,17 +194,16 @@ class Option(OnlyOption):
|
|||
_index = None
|
||||
else:
|
||||
_index = index
|
||||
try:
|
||||
opt_value = context.getattr(path, validate=False,
|
||||
index=_index,
|
||||
force_permissive=True,
|
||||
returns_raise=True)
|
||||
if isinstance(opt_value, Exception):
|
||||
if isinstance(opt_value, PropertiesOptionError):
|
||||
force_permissive=True)
|
||||
except PropertiesOptionError as err:
|
||||
if debug: # pragma: no cover
|
||||
log.debug('propertyerror in _launch_consistency: {0}'.format(opt_value))
|
||||
log.debug('propertyerror in _launch_consistency: {0}'.format(err))
|
||||
if transitive:
|
||||
opt_value.set_orig_opt(option)
|
||||
return opt_value
|
||||
err.set_orig_opt(option)
|
||||
raise err
|
||||
else:
|
||||
opt_value = None
|
||||
else: # pragma: no cover
|
||||
|
@ -472,7 +471,10 @@ class Option(OnlyOption):
|
|||
return False
|
||||
|
||||
def impl_get_master_slaves(self):
|
||||
return getattr(self, '_master_slaves', None)
|
||||
masterslave = getattr(self, '_master_slaves', None)
|
||||
if masterslave is None:
|
||||
return masterslave
|
||||
return masterslave()
|
||||
|
||||
def impl_getdoc(self):
|
||||
"accesses the Option's doc"
|
||||
|
@ -480,7 +482,7 @@ class Option(OnlyOption):
|
|||
|
||||
def _valid_consistencies(self, other_opts, init=True, func=None):
|
||||
if self._is_subdyn():
|
||||
dynod = self._subdyn
|
||||
dynod = self._subdyn()
|
||||
else:
|
||||
dynod = None
|
||||
if self.impl_is_submulti():
|
||||
|
@ -495,10 +497,11 @@ class Option(OnlyOption):
|
|||
if dynod is None:
|
||||
raise ConfigError(_('almost one option in consistency is '
|
||||
'in a dynoptiondescription but not all'))
|
||||
if dynod != opt._subdyn:
|
||||
subod = opt._subdyn()
|
||||
if dynod != subod:
|
||||
raise ConfigError(_('option in consistency must be in same'
|
||||
' dynoptiondescription'))
|
||||
dynod = opt._subdyn
|
||||
dynod = subod
|
||||
elif dynod is not None:
|
||||
raise ConfigError(_('almost one option in consistency is in a '
|
||||
'dynoptiondescription but not all'))
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
# ____________________________________________________________
|
||||
from copy import copy
|
||||
import re
|
||||
import weakref
|
||||
|
||||
|
||||
from ..i18n import _
|
||||
|
@ -72,8 +73,6 @@ class CacheOptionDescription(BaseOption):
|
|||
cache_option, force_store_values,
|
||||
_dependencies)
|
||||
else:
|
||||
if option.impl_is_master_slaves('master'):
|
||||
option._add_dependency(option.impl_get_master_slaves())
|
||||
option._set_readonly()
|
||||
is_multi = option.impl_is_multi()
|
||||
if not option._is_symlinkoption() and 'force_store_value' in option.impl_getproperties():
|
||||
|
@ -207,10 +206,17 @@ class CacheOptionDescription(BaseOption):
|
|||
class OptionDescriptionWalk(CacheOptionDescription):
|
||||
__slots__ = ('_children',)
|
||||
|
||||
def impl_get_options_paths(self, bytype, byname, _subpath, only_first, context):
|
||||
def impl_get_options_paths(self,
|
||||
bytype,
|
||||
byname,
|
||||
_subpath,
|
||||
only_first,
|
||||
context):
|
||||
find_results = []
|
||||
|
||||
def _rebuild_dynpath(path, suffix, dynopt):
|
||||
def _rebuild_dynpath(path,
|
||||
suffix,
|
||||
dynopt):
|
||||
found = False
|
||||
spath = path.split('.')
|
||||
for length in xrange(1, len(spath)):
|
||||
|
@ -226,19 +232,22 @@ class OptionDescriptionWalk(CacheOptionDescription):
|
|||
subpath = subpath + '.' + spath[slength] + suffix
|
||||
return subpath
|
||||
|
||||
def _filter_by_name(path, option):
|
||||
def _filter_by_name(path,
|
||||
option):
|
||||
name = option.impl_getname()
|
||||
if option._is_subdyn():
|
||||
if byname.startswith(name):
|
||||
found = False
|
||||
for suffix in option._subdyn._impl_get_suffixes(
|
||||
subdyn = option._subdyn()
|
||||
for suffix in subdyn._impl_get_suffixes(
|
||||
context):
|
||||
if byname == name + suffix:
|
||||
found = True
|
||||
path = _rebuild_dynpath(path, suffix,
|
||||
option._subdyn)
|
||||
option = option._impl_to_dyn(
|
||||
name + suffix, path)
|
||||
path = _rebuild_dynpath(path,
|
||||
suffix,
|
||||
subdyn)
|
||||
option = option._impl_to_dyn(name + suffix,
|
||||
path)
|
||||
break
|
||||
if not found:
|
||||
return False
|
||||
|
@ -248,8 +257,10 @@ class OptionDescriptionWalk(CacheOptionDescription):
|
|||
find_results.append((path, option))
|
||||
return True
|
||||
|
||||
def _filter_by_type(path, option):
|
||||
if isinstance(option, bytype):
|
||||
def _filter_by_type(path,
|
||||
option):
|
||||
if isinstance(option,
|
||||
bytype):
|
||||
#if byname is not None, check option byname in _filter_by_name
|
||||
#not here
|
||||
if byname is None:
|
||||
|
@ -257,7 +268,8 @@ class OptionDescriptionWalk(CacheOptionDescription):
|
|||
name = option.impl_getname()
|
||||
for suffix in option._subdyn._impl_get_suffixes(
|
||||
context):
|
||||
spath = _rebuild_dynpath(path, suffix,
|
||||
spath = _rebuild_dynpath(path,
|
||||
suffix,
|
||||
option._subdyn)
|
||||
find_results.append((spath, option._impl_to_dyn(
|
||||
name + suffix, spath)))
|
||||
|
@ -485,9 +497,11 @@ class OptionDescription(OptionDescriptionWalk):
|
|||
def __getstate__(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
def _impl_get_suffixes(self, context):
|
||||
def _impl_get_suffixes(self,
|
||||
context):
|
||||
callback, callback_params = self.impl_get_callback()
|
||||
values = carry_out_calculation(self, context=context,
|
||||
values = carry_out_calculation(self,
|
||||
context=context,
|
||||
callback=callback,
|
||||
callback_params=callback_params)
|
||||
if len(values) > len(set(values)):
|
||||
|
@ -497,15 +511,28 @@ class OptionDescription(OptionDescriptionWalk):
|
|||
raise ValueError(_("invalid suffix: {0} for option").format(val))
|
||||
return values
|
||||
|
||||
def impl_validate_value(self, option, value, context):
|
||||
def impl_validate_value(self,
|
||||
option,
|
||||
value,
|
||||
context):
|
||||
pass
|
||||
|
||||
|
||||
class DynOptionDescription(OptionDescription):
|
||||
def __init__(self, name, doc, children, requires=None, properties=None,
|
||||
callback=None, callback_params=None):
|
||||
super(DynOptionDescription, self).__init__(name, doc, children,
|
||||
requires, properties)
|
||||
def __init__(self,
|
||||
name,
|
||||
doc,
|
||||
children,
|
||||
requires=None,
|
||||
properties=None,
|
||||
callback=None,
|
||||
callback_params=None):
|
||||
|
||||
super(DynOptionDescription, self).__init__(name,
|
||||
doc,
|
||||
children,
|
||||
requires,
|
||||
properties)
|
||||
for child in children:
|
||||
if isinstance(child, OptionDescription):
|
||||
if child.impl_get_group_type() != groups.master:
|
||||
|
@ -517,9 +544,12 @@ class DynOptionDescription(OptionDescription):
|
|||
raise ConfigError(_('cannot set symlinkoption in a '
|
||||
'dynoptiondescription'))
|
||||
child._impl_setsubdyn(self)
|
||||
self.impl_set_callback(callback, callback_params)
|
||||
self.impl_set_callback(callback,
|
||||
callback_params)
|
||||
|
||||
def _validate_callback(self, callback, callback_params):
|
||||
def _validate_callback(self,
|
||||
callback,
|
||||
callback_params):
|
||||
if callback is None:
|
||||
raise ConfigError(_('callback is mandatory for dynoptiondescription'))
|
||||
|
||||
|
@ -532,15 +562,22 @@ class SynDynOptionDescription(object):
|
|||
self._name = name
|
||||
self._suffix = suffix
|
||||
|
||||
def __getattr__(self, name, context=undefined):
|
||||
def __getattr__(self,
|
||||
name,
|
||||
context=undefined):
|
||||
if name in dir(self._opt):
|
||||
return getattr(self._opt, name)
|
||||
return self._opt._getattr(name, suffix=self._suffix, context=context)
|
||||
return getattr(self._opt,
|
||||
name)
|
||||
return self._opt._getattr(name,
|
||||
suffix=self._suffix,
|
||||
context=context)
|
||||
|
||||
def impl_getname(self):
|
||||
return self._name
|
||||
|
||||
def _impl_getchildren(self, dyn=True, context=undefined):
|
||||
def _impl_getchildren(self,
|
||||
dyn=True,
|
||||
context=undefined):
|
||||
children = []
|
||||
for child in self._opt._impl_getchildren():
|
||||
yield(self._opt._impl_get_dynchild(child, self._suffix))
|
||||
|
@ -608,7 +645,7 @@ class MasterSlaves(OptionDescription):
|
|||
"not refered a slave's ones"))
|
||||
#everything is ok, store references
|
||||
for child in children:
|
||||
child._master_slaves = self
|
||||
child._master_slaves = weakref.ref(self)
|
||||
master._add_dependency(self)
|
||||
|
||||
def is_master(self, opt):
|
||||
|
@ -643,7 +680,7 @@ class MasterSlaves(OptionDescription):
|
|||
c_opt = opt._opt
|
||||
else:
|
||||
c_opt = opt
|
||||
return c_opt in self._children[1]
|
||||
return child in self._children[1]
|
||||
|
||||
def reset(self,
|
||||
opt,
|
||||
|
@ -714,10 +751,16 @@ class MasterSlaves(OptionDescription):
|
|||
setting_properties,
|
||||
check_frozen)
|
||||
else:
|
||||
return self._getslave(values, opt, path, validate,
|
||||
force_permissive, trusted_cached_properties,
|
||||
validate_properties, setting_properties,
|
||||
self_properties, index,
|
||||
return self._getslave(values,
|
||||
opt,
|
||||
path,
|
||||
validate,
|
||||
force_permissive,
|
||||
trusted_cached_properties,
|
||||
validate_properties,
|
||||
setting_properties,
|
||||
self_properties,
|
||||
index,
|
||||
check_frozen)
|
||||
|
||||
def _getmaster(self,
|
||||
|
@ -768,17 +811,19 @@ class MasterSlaves(OptionDescription):
|
|||
master = self.getmaster(opt)
|
||||
context = values._getcontext()
|
||||
masterp = master.impl_getpath(context)
|
||||
mastervalue = values.get_cached_value(master, path=masterp, validate=validate,
|
||||
try:
|
||||
mastervalue = values.get_cached_value(master,
|
||||
path=masterp,
|
||||
validate=validate,
|
||||
force_permissive=force_permissive,
|
||||
validate_properties=validate_properties,
|
||||
self_properties=self_properties,
|
||||
from_masterslave=True,
|
||||
setting_properties=setting_properties,
|
||||
check_frozen=check_frozen)
|
||||
if isinstance(mastervalue, Exception):
|
||||
if isinstance(mastervalue, PropertiesOptionError):
|
||||
except PropertiesOptionError as mastervalue:
|
||||
mastervalue.set_orig_opt(opt)
|
||||
return mastervalue
|
||||
raise mastervalue
|
||||
masterlen = len(mastervalue)
|
||||
#self._master_is_meta = values._is_meta(master, masterp, force_permissive=force_permissive)
|
||||
multi = list() # values._get_multi(opt, path)
|
||||
|
@ -797,7 +842,10 @@ class MasterSlaves(OptionDescription):
|
|||
else:
|
||||
indexes = [index]
|
||||
for idx in indexes:
|
||||
value = values.get_cached_value(opt, path, validate,
|
||||
try:
|
||||
value = values.get_cached_value(opt,
|
||||
path,
|
||||
validate,
|
||||
force_permissive,
|
||||
trusted_cached_properties,
|
||||
validate_properties,
|
||||
|
@ -808,16 +856,13 @@ class MasterSlaves(OptionDescription):
|
|||
setting_properties=setting_properties,
|
||||
from_masterslave=True,
|
||||
check_frozen=check_frozen)
|
||||
if isinstance(value, Exception):
|
||||
if isinstance(value, PropertiesOptionError):
|
||||
err = value
|
||||
except PropertiesOptionError as perr:
|
||||
err = perr
|
||||
if index is None:
|
||||
multi.append(value)
|
||||
multi.append(err)
|
||||
else:
|
||||
multi = value
|
||||
else:
|
||||
return value
|
||||
elif index is None:
|
||||
multi = err
|
||||
if index is None:
|
||||
multi.append(value)
|
||||
else:
|
||||
multi = value
|
||||
|
@ -861,14 +906,16 @@ class MasterSlaves(OptionDescription):
|
|||
master = self.getmaster(None)
|
||||
if masterp is None:
|
||||
masterp = master.impl_getpath(values._getcontext())
|
||||
value = self.getitem(values,
|
||||
value = self._getmaster(values,
|
||||
master,
|
||||
masterp,
|
||||
validate,
|
||||
force_permissive,
|
||||
validate,
|
||||
undefined,
|
||||
None,
|
||||
True,
|
||||
setting_properties=setting_properties)
|
||||
setting_properties,
|
||||
False)
|
||||
if isinstance(value, Exception):
|
||||
return value
|
||||
return len(value)
|
||||
|
|
|
@ -575,24 +575,29 @@ class Settings(object):
|
|||
else:
|
||||
opt_type = 'option'
|
||||
if 'frozen' in properties:
|
||||
return PropertiesOptionError(_('cannot change the value for '
|
||||
raise PropertiesOptionError(_('cannot change the value for '
|
||||
'option "{0}" this option is'
|
||||
' frozen').format(
|
||||
opt_or_descr.impl_getname()),
|
||||
props, self, datas, opt_type)
|
||||
props,
|
||||
self,
|
||||
datas,
|
||||
opt_type)
|
||||
else:
|
||||
if len(props) == 1:
|
||||
prop_msg = _('property')
|
||||
else:
|
||||
prop_msg = _('properties')
|
||||
return PropertiesOptionError(_('cannot access to {0} "{1}" '
|
||||
raise PropertiesOptionError(_('cannot access to {0} "{1}" '
|
||||
'because has {2} {3}'
|
||||
'').format(opt_type,
|
||||
opt_or_descr.impl_get_display_name(),
|
||||
prop_msg,
|
||||
display_list(props)),
|
||||
props,
|
||||
self, datas, opt_type)
|
||||
self,
|
||||
datas,
|
||||
opt_type)
|
||||
|
||||
def setpermissive(self, permissive, opt=None, path=None):
|
||||
"""
|
||||
|
@ -728,20 +733,21 @@ class Settings(object):
|
|||
idx = index
|
||||
else:
|
||||
idx = None
|
||||
value = context.getattr(reqpath, force_permissive=True,
|
||||
try:
|
||||
value = context.getattr(reqpath,
|
||||
force_permissive=True,
|
||||
_setting_properties=setting_properties,
|
||||
index=idx, returns_raise=True)
|
||||
if isinstance(value, Exception):
|
||||
if isinstance(value, PropertiesOptionError):
|
||||
index=idx)
|
||||
except PropertiesOptionError as err:
|
||||
if not transitive:
|
||||
if all_properties is None:
|
||||
all_properties = []
|
||||
for requires in opt.impl_getrequires():
|
||||
for require in requires:
|
||||
all_properties.append(require[1])
|
||||
if not set(value.proptype) - set(all_properties):
|
||||
if not set(err.proptype) - set(all_properties):
|
||||
continue
|
||||
properties = value.proptype
|
||||
properties = err.proptype
|
||||
if same_action and action not in properties: # pragma: optional cover
|
||||
if len(properties) == 1:
|
||||
prop_msg = _('property')
|
||||
|
@ -753,12 +759,10 @@ class Settings(object):
|
|||
option.impl_get_display_name(),
|
||||
prop_msg,
|
||||
display_list(properties)))
|
||||
orig_value = value
|
||||
orig_value = err
|
||||
# transitive action, force expected
|
||||
value = expected[0]
|
||||
inverse = False
|
||||
else: # pragma: no cover
|
||||
raise value
|
||||
else:
|
||||
orig_value = value
|
||||
if (not inverse and value in expected or
|
||||
|
|
|
@ -93,15 +93,15 @@ class Values(object):
|
|||
meta = self._getcontext().cfgimpl_get_meta()
|
||||
if meta is not None:
|
||||
# retrieved value from meta config
|
||||
try:
|
||||
value = meta.cfgimpl_get_values().get_cached_value(opt,
|
||||
path,
|
||||
index=index,
|
||||
_orig_context=_orig_context)
|
||||
if isinstance(value, Exception):
|
||||
except PropertiesOptionError:
|
||||
# if properties error, return an other default value
|
||||
if not isinstance(value, PropertiesOptionError): # pragma: no cover
|
||||
# unexpected error, should not happened
|
||||
raise value
|
||||
pass
|
||||
else:
|
||||
return value
|
||||
|
||||
|
@ -476,15 +476,15 @@ class Values(object):
|
|||
context = self._getcontext()
|
||||
setting = context.cfgimpl_get_settings()
|
||||
config_error = None
|
||||
try:
|
||||
value = self._getvalue(opt,
|
||||
path,
|
||||
self_properties,
|
||||
index,
|
||||
validate,
|
||||
_orig_context)
|
||||
if isinstance(value, Exception):
|
||||
except ConfigError as value:
|
||||
value_error = True
|
||||
if isinstance(value, ConfigError):
|
||||
# For calculating properties, we need value (ie for mandatory
|
||||
# value).
|
||||
# If value is calculating with a PropertiesOptionError's option
|
||||
|
@ -496,8 +496,6 @@ class Values(object):
|
|||
# value is not set, for 'undefined' (cannot set None because of
|
||||
# mandatory property)
|
||||
value = undefined
|
||||
else: # pragma: no cover
|
||||
raise value
|
||||
else:
|
||||
value_error = False
|
||||
if validate:
|
||||
|
@ -807,6 +805,7 @@ class Values(object):
|
|||
setting_properties = context.cfgimpl_get_settings()._getproperties()
|
||||
setting_properties.update(['mandatory', 'empty'])
|
||||
def _is_properties_option(err, path):
|
||||
#FIXME hum ...
|
||||
if not isinstance(err, Exception):
|
||||
pass
|
||||
elif isinstance(err, PropertiesOptionError):
|
||||
|
@ -871,6 +870,7 @@ class Values(object):
|
|||
context.cfgimpl_reset_cache()
|
||||
for path in context.cfgimpl_get_description().impl_getpaths(
|
||||
include_groups=True):
|
||||
err = context.getattr(path, returns_raise=True)
|
||||
if isinstance(err, Exception) and not isinstance(err, PropertiesOptionError): # pragma: no cover
|
||||
raise err
|
||||
try:
|
||||
err = context.getattr(path)
|
||||
except PropertiesOptionError as err:
|
||||
pass
|
||||
|
|
Loading…
Reference in New Issue