- add api.owner.get() to get default owner for a context + tests

- slave: get length for a specified slave and test
- add test for deref objects and default_multi
- add issubmulti, getdefault, getdefaultmulti
- start metaconfig support in api
This commit is contained in:
Emmanuel Garette 2017-11-16 21:30:07 +01:00
parent 007a22ca94
commit 93fe29b651
6 changed files with 371 additions and 168 deletions

View File

@ -177,7 +177,8 @@ def test_callback_submulti_list_list():
cfg = Config(od) cfg = Config(od)
cfg.read_write() cfg.read_write()
api = getapi(cfg) api = getapi(cfg)
owner = cfg.cfgimpl_get_settings().getowner() owner = api.owner.get()
assert owner == 'user'
assert api.option('multi').value.get() == [['val', 'val']] assert api.option('multi').value.get() == [['val', 'val']]
assert api.option('multi').owner.isdefault() assert api.option('multi').owner.isdefault()
api.option('multi').value.set([['val', 'val'], undefined]) api.option('multi').value.set([['val', 'val'], undefined])
@ -203,46 +204,3 @@ def test_callback_submulti_list_list():
# multi.append() # multi.append()
# assert conf1.multi == [['val', None]] # assert conf1.multi == [['val', None]]
# assert meta.multi == [['val']] # assert meta.multi == [['val']]
# ____________________________________________________________
# Master Slaves
def test_values_with_master_and_slaves_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)
api = getapi(cfg)
cfg.read_write()
owner = cfg.cfgimpl_get_settings().getowner()
#FIXME
assert interface1.impl_get_group_type() == groups.master
assert api.option('f_ip_admin_eth0.ip_admin_eth0').owner.isdefault()
#FIXME raises(IndexError, "api.option('f_ip_admin_eth0.netmask_admin_eth0', 0).value.get()")
api.option('f_ip_admin_eth0.ip_admin_eth0').value.set(['192.168.230.145'])
assert api.option('f_ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.230.145']
assert api.option('f_ip_admin_eth0.netmask_admin_eth0', 0).value.get() == []
#FIXME raises(IndexError, "api.option('f_ip_admin_eth0.netmask_admin_eth0', 1).value.get()")
assert api.option('f_ip_admin_eth0.ip_admin_eth0').owner.get() == owner
assert api.option('f_ip_admin_eth0.netmask_admin_eth0', 0).owner.isdefault()
api.option('f_ip_admin_eth0.ip_admin_eth0').value.set(['192.168.230.145', '192.168.230.147'])
assert api.option('f_ip_admin_eth0.netmask_admin_eth0', 0).value.get() == []
assert api.option('f_ip_admin_eth0.netmask_admin_eth0', 1).value.get() == []
#FIXME raises(IndexError, "api.option('f_ip_admin_eth0.netmask_admin_eth0', 2).value.get()")
#FIXME raises(IndexError, "api.option('f_ip_admin_eth0.netmask_admin_eth0', 2).value.set(['255.255.255.0'])")
api.option('f_ip_admin_eth0.netmask_admin_eth0', 0).value.set(['255.255.255.0'])
assert api.option('f_ip_admin_eth0.netmask_admin_eth0', 0).value.get() == ['255.255.255.0']
assert api.option('f_ip_admin_eth0.netmask_admin_eth0', 1).value.get() == []
api.option('f_ip_admin_eth0.netmask_admin_eth0', 1).value.set(['255.255.255.255'])
assert api.option('f_ip_admin_eth0.netmask_admin_eth0', 0).value.get() == ['255.255.255.0']
assert api.option('f_ip_admin_eth0.netmask_admin_eth0', 1).value.get() == ['255.255.255.255']
assert api.option('f_ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.230.145', '192.168.230.147']
raises(ValueError, "api.option('f_ip_admin_eth0.ip_admin_eth0').value.set(['192.168.230.145'])")
api.option('f_ip_admin_eth0.ip_admin_eth0').value.pop(1)
assert api.option('f_ip_admin_eth0.ip_admin_eth0').value.get() == ['192.168.230.145']
assert api.option('f_ip_admin_eth0.netmask_admin_eth0', 0).value.get() == ['255.255.255.0']
#FIXME raises(IndexError, "api.option('f_ip_admin_eth0.netmask_admin_eth0', 1).value.get()")

View File

@ -1,20 +1,37 @@
"""test API """test API
""" """
import weakref
import pytest import pytest
from py.test import raises from py.test import raises
import weakref
from .autopath import do_autopath from .autopath import do_autopath
do_autopath() do_autopath()
from tiramisu import Config, StrOption, OptionDescription, MasterSlaves, DynOptionDescription, \ from tiramisu import Config, MetaConfig, \
getapi StrOption, OptionDescription, MasterSlaves, DynOptionDescription, \
getapi, submulti, undefined
from tiramisu.error import PropertiesOptionError, APIError from tiramisu.error import PropertiesOptionError, APIError
from collections import OrderedDict from collections import OrderedDict
ICON = u'\u2937' ICON = u'\u2937'
OPTIONS_TYPE = {'str': {'type': str, OPTIONS_TYPE = {'str': {'type': str,
'option': StrOption} 'option': StrOption}
} }
PROPERTIES = ['hidden', 'disabled'] PROPERTIES = ['hidden', 'disabled']
OWNER = 'user'
# multi is False
FIRST_VALUE = 'myvalue'
SECOND_VALUE = 'myvalue1'
EMPTY_VALUE = None
# multi is True
LIST_FIRST_VALUE = ['myvalue']
LIST_SECOND_VALUE = ['myvalue', 'myvalue1']
LIST_EMPTY_VALUE = []
# multi is submulti
SUBLIST_FIRST_VALUE = [['myvalue']]
SUBLIST_SECOND_VALUE = [['myvalue'], ['myvalue1', 'myvalue2']]
SUBLIST_EMPTY_VALUE = []
DISPLAY = True DISPLAY = True
#DISPLAY = False #DISPLAY = False
@ -94,6 +111,11 @@ def autocheck_owner_without_value(api, path, **kwargs):
else: else:
raises(PropertiesOptionError, "api.forcepermissive.option(path).owner.isdefault()") raises(PropertiesOptionError, "api.forcepermissive.option(path).owner.isdefault()")
def _getdefault(api, path, multi, isslave, submulti_):
empty_value = api.unrestraint.option(path).option.getdefault()
if isslave and empty_value == []:
empty_value = api.unrestraint.option(path).option.getdefaultmulti()
return empty_value
@autocheck @autocheck
def autocheck_value(api, path, **kwargs): def autocheck_value(api, path, **kwargs):
@ -102,25 +124,27 @@ def autocheck_value(api, path, **kwargs):
# check if is a multi, a master or a slave # check if is a multi, a master or a slave
if not kwargs.get('propertyerror', False): if not kwargs.get('propertyerror', False):
multi = api.forcepermissive.option(path).option.ismulti() multi = api.forcepermissive.option(path).option.ismulti()
submulti_ = api.forcepermissive.option(path).option.issubmulti()
ismaster = api.forcepermissive.option(path).option.ismaster() ismaster = api.forcepermissive.option(path).option.ismaster()
isslave = api.forcepermissive.option(path).option.isslave() isslave = api.forcepermissive.option(path).option.isslave()
else: else:
raises(PropertiesOptionError, "api.forcepermissive.option(path).option.ismulti()") raises(PropertiesOptionError, "api.forcepermissive.option(path).option.ismulti()")
multi = api.unrestraint.option(path).option.ismulti() multi = api.unrestraint.option(path).option.ismulti()
submulti_ = api.unrestraint.option(path).option.issubmulti()
ismaster = api.unrestraint.option(path).option.ismaster() ismaster = api.unrestraint.option(path).option.ismaster()
isslave = api.unrestraint.option(path).option.isslave() isslave = api.unrestraint.option(path).option.isslave()
# set default value (different if value is multi or not) # set default value (different if value is multi or not)
if not multi: if not multi:
first_value = 'myvalue' first_value = FIRST_VALUE
second_value = 'myvalue1' second_value = SECOND_VALUE
elif submulti_ is False:
first_value = LIST_FIRST_VALUE
second_value = LIST_SECOND_VALUE
else: else:
first_value = ['myvalue'] first_value = SUBLIST_FIRST_VALUE
second_value = ['myvalue', 'myvalue1'] second_value = SUBLIST_SECOND_VALUE
if multi and not isslave: empty_value = _getdefault(api, path, multi, isslave, submulti_)
empty_value = []
else:
empty_value = None
# test default value (should be empty) without permissive # test default value (should be empty) without permissive
# cannot test for slave (we cannot get all values for a slave) # cannot test for slave (we cannot get all values for a slave)
@ -239,23 +263,63 @@ def autocheck_value(api, path, **kwargs):
raises(PropertiesOptionError, "api.forcepermissive.option(path).value.get()") raises(PropertiesOptionError, "api.forcepermissive.option(path).value.get()")
@autocheck
def autocheck_value_slave(api, path, **kwargs):
multi = api.unrestraint.option(path).option.ismulti()
isslave = api.unrestraint.option(path).option.isslave()
if not isslave:
#FIXME verifier pas de len !
return
if kwargs.get('propertyerror', False):
return
submulti_ = api.forcepermissive.option(path).option.issubmulti()
if not kwargs.get('permissive', False):
length = api.option(path).value.len()
else:
length = api.forcepermissive.option(path).value.len()
assert length == 2
value = []
for idx in range(length):
value.append(api.forcepermissive.option(path, idx).value.get())
if not submulti_:
second_value = LIST_SECOND_VALUE
else:
second_value = SUBLIST_SECOND_VALUE
empty_value = _getdefault(api, path, multi, isslave, submulti_)
assert value == [empty_value, second_value[1]]
# cannot access to a slave with index too high
if submulti_ is False:
value = LIST_FIRST_VALUE[0]
else:
value = SUBLIST_FIRST_VALUE[0]
raises(IndexError, "api.forcepermissive.option(path, length).value.get()")
raises(IndexError, "api.forcepermissive.option(path, length).value.set(value)")
raises(IndexError, "api.forcepermissive.option(path, length).value.reset()")
raises(IndexError, "api.forcepermissive.option(path, length).owner.get()")
raises(IndexError, "api.forcepermissive.option(path, length).owner.isdefault()")
raises(IndexError, "api.forcepermissive.option(path, length).property.get()")
raises(IndexError, "api.forcepermissive.option(path, length).owner.set('new_user')")
raises(IndexError, "api.forcepermissive.option(path, length).property.set(('prop',))")
@autocheck @autocheck
def autocheck_reset_value(api, path, **kwargs): def autocheck_reset_value(api, path, **kwargs):
# check if is a multi, a master or a slave # check if is a multi, a master or a slave
multi = api.unrestraint.option(path).option.ismulti() multi = api.unrestraint.option(path).option.ismulti()
submulti_ = api.unrestraint.option(path).option.issubmulti()
isslave = api.unrestraint.option(path).option.isslave() isslave = api.unrestraint.option(path).option.isslave()
# set default value (different if value is multi or not) # set default value (different if value is multi or not)
if not multi: if not multi:
first_value = 'myvalue' first_value = FIRST_VALUE
second_value = 'myvalue1' second_value = SECOND_VALUE
elif submulti_ is False:
first_value = LIST_FIRST_VALUE
second_value = LIST_SECOND_VALUE
else: else:
first_value = ['myvalue'] first_value = SUBLIST_FIRST_VALUE
second_value = ['myvalue', 'myvalue1'] second_value = SUBLIST_SECOND_VALUE
if multi and not isslave: empty_value = _getdefault(api, path, multi, isslave, submulti_)
empty_value = []
else:
empty_value = None
# reset value without permissive # reset value without permissive
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False): if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
@ -332,7 +396,7 @@ def autocheck_display(api, path, **kwargs):
"""re set value """re set value
""" """
#FIXME utile ? #FIXME utile ?
print(api.config) assert api.config
@autocheck @autocheck
@ -554,13 +618,16 @@ def autocheck_owner_with_value(api, path, **kwargs):
raises(PropertiesOptionError, "api.forcepermissive.option(path).option.isslave()") raises(PropertiesOptionError, "api.forcepermissive.option(path).option.isslave()")
isslave = api.unrestraint.option(path).option.isslave() isslave = api.unrestraint.option(path).option.isslave()
owner = api.owner.get()
assert owner == OWNER
# get owner without permissive # get owner without permissive
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False): if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
if not isslave: if not isslave:
assert api.option(path).owner.get() == 'user' assert api.option(path).owner.get() == owner
else: else:
assert api.option(path, 0).owner.get() == 'user' assert api.option(path, 0).owner.get() == owner
assert api.option(path, 1).owner.get() == 'user' assert api.option(path, 1).owner.get() == owner
else: else:
if not isslave: if not isslave:
raises(PropertiesOptionError, "api.option(path).owner.get()") raises(PropertiesOptionError, "api.option(path).owner.get()")
@ -571,10 +638,10 @@ def autocheck_owner_with_value(api, path, **kwargs):
# get owner with permissive # get owner with permissive
if not kwargs.get('propertyerror', False): if not kwargs.get('propertyerror', False):
if not isslave: if not isslave:
assert api.forcepermissive.option(path).owner.get() == 'user' assert api.forcepermissive.option(path).owner.get() == owner
else: else:
assert api.forcepermissive.option(path, 0).owner.get() == 'default' assert api.forcepermissive.option(path, 0).owner.get() == 'default'
assert api.forcepermissive.option(path, 1).owner.get() == 'user' assert api.forcepermissive.option(path, 1).owner.get() == owner
else: else:
if not isslave: if not isslave:
raises(PropertiesOptionError, "api.forcepermissive.option(path).owner.get()") raises(PropertiesOptionError, "api.forcepermissive.option(path).owner.get()")
@ -628,10 +695,11 @@ def autocheck_set_owner(api, path, **kwargs):
assert api.option(path, 1).owner.get() == 'new_user' assert api.option(path, 1).owner.get() == 'new_user'
assert api.forcepermissive.option(path, 1).owner.get() == 'new_user' assert api.forcepermissive.option(path, 1).owner.get() == 'new_user'
elif not kwargs.get('propertyerror', False): elif not kwargs.get('propertyerror', False):
owner = api.owner.get()
if not isslave: if not isslave:
assert api.forcepermissive.option(path).owner.get() == 'user' assert api.forcepermissive.option(path).owner.get() == owner
else: else:
assert api.forcepermissive.option(path, 1).owner.get() == 'user' assert api.forcepermissive.option(path, 1).owner.get() == owner
# set owner with permissive # set owner with permissive
if not kwargs.get('propertyerror', False): if not kwargs.get('propertyerror', False):
@ -691,25 +759,32 @@ def autocheck_permissive(api, path, **kwargs):
# check if is a multi, a master or a slave # check if is a multi, a master or a slave
if not kwargs.get('propertyerror', False): if not kwargs.get('propertyerror', False):
multi = api.forcepermissive.option(path).option.ismulti() multi = api.forcepermissive.option(path).option.ismulti()
submulti_ = api.forcepermissive.option(path).option.issubmulti()
ismaster = api.forcepermissive.option(path).option.ismaster() ismaster = api.forcepermissive.option(path).option.ismaster()
isslave = api.forcepermissive.option(path).option.isslave() isslave = api.forcepermissive.option(path).option.isslave()
else: else:
raises(PropertiesOptionError, "api.forcepermissive.option(path).option.ismulti()") raises(PropertiesOptionError, "api.forcepermissive.option(path).option.ismulti()")
multi = api.unrestraint.option(path).option.ismulti() multi = api.unrestraint.option(path).option.ismulti()
submulti_ = api.unrestraint.option(path).option.issubmulti()
ismaster = api.unrestraint.option(path).option.ismaster() ismaster = api.unrestraint.option(path).option.ismaster()
isslave = api.unrestraint.option(path).option.isslave() isslave = api.unrestraint.option(path).option.isslave()
# set default value (different if value is multi or not) # set default value (different if value is multi or not)
if not multi: if not multi:
first_value = 'myvalue' first_value = FIRST_VALUE
second_value = 'myvalue1' second_value = SECOND_VALUE
elif submulti_ is False:
first_value = LIST_FIRST_VALUE
second_value = LIST_SECOND_VALUE
else: else:
first_value = ['myvalue'] first_value = SUBLIST_FIRST_VALUE
second_value = ['myvalue', 'myvalue1'] second_value = SUBLIST_SECOND_VALUE
if multi and not isslave: if multi and not isslave:
empty_value = [] empty_value = LIST_EMPTY_VALUE
elif submulti_ and isslave:
empty_value = SUBLIST_EMPTY_VALUE
else: else:
empty_value = None empty_value = EMPTY_VALUE
# cannot access to hidden value without forcepermissive # cannot access to hidden value without forcepermissive
# and to disabled value (with forcepermissive too) # and to disabled value (with forcepermissive too)
@ -765,35 +840,78 @@ def autocheck_permissive(api, path, **kwargs):
def check_all(api, path, multi, **kwargs): def check_all(api, path, meta, multi, default, default_multi, **kwargs):
if DISPLAY: if DISPLAY:
text = u' {} launch tests for {}'.format(ICON, path) text = u' {} launch tests for {}'.format(ICON, path, multi, default)
if multi: if multi is True:
text += u' as a multi' text += u' as a multi'
elif multi is submulti:
text += u' as a submulti'
if default is True:
text += u' with default'
if multi is True:
text += u' with default value'
if default_multi is True:
text += u' with default multi'
text += u', kwargs: {}'.format(kwargs) text += u', kwargs: {}'.format(kwargs)
print(text) print(text)
for func in autocheck_registers: for func in autocheck_registers:
if DISPLAY: if DISPLAY:
print(u' {} {}'.format(ICON, func.__name__)) print(u' {} {}'.format(ICON, func.__name__))
func(api, path, **kwargs) try:
func(api, path, **kwargs)
except Exception as err:
msg = u'error in function {} for {}'.format(func.__name__, path)
if multi is True:
msg += u' as a multi'
elif multi is submulti:
msg += u' as a submulti'
if multi is True:
msg += u' with default value'
print(u'{}: {}'.format(msg, kwargs))
raise err
def make_api(options, multi): def check_deref(weakrefs):
"""try if all elements are dereferenced
"""
for wrf in weakrefs:
assert wrf() is None
def make_api(options, meta, multi, default, default_multi):
weakrefs = [] weakrefs = []
def make_option(path, option_infos): def make_option(path, option_infos):
#FIXME #FIXME
option_type = 'str' option_type = 'str'
option_properties = [] option_properties = []
isslave = False
if option_infos is not None: if option_infos is not None:
for prop in PROPERTIES: for prop in PROPERTIES:
if option_infos.get(prop, False) is True: if option_infos.get(prop, False) is True:
option_properties.append(prop) option_properties.append(prop)
isslave = option_infos.get('slave', False)
args = [path, "{}'s option".format(path)] args = [path, "{}'s option".format(path)]
kwargs = {} kwargs = {}
if option_properties != []: if option_properties != []:
kwargs['properties'] = tuple(option_properties) kwargs['properties'] = tuple(option_properties)
if multi: if multi:
kwargs['multi'] = True kwargs['multi'] = multi
if default and not submulti:
if multi is False:
value = FIRST_VALUE
elif multi is True:
value = LIST_FIRST_VALUE
else:
value = SUBLIST_EMPTY_VALUE
kwargs['default'] = value
if default_multi:
if multi is not submulti:
value = SECOND_VALUE
else:
value = LIST_SECOND_VALUE
kwargs['default_multi'] = value
tiramisu_option = OPTIONS_TYPE[option_type]['option'] tiramisu_option = OPTIONS_TYPE[option_type]['option']
obj = tiramisu_option(*args, **kwargs) obj = tiramisu_option(*args, **kwargs)
weakrefs.append(weakref.ref(obj)) weakrefs.append(weakref.ref(obj))
@ -849,6 +967,9 @@ def make_api(options, multi):
return None, None return None, None
cfg = Config(rootod, session_id='conftest') cfg = Config(rootod, session_id='conftest')
weakrefs.append(weakref.ref(cfg)) weakrefs.append(weakref.ref(cfg))
if meta:
cfg = MetaConfig([cfg], session_id='metatest')
weakrefs.append(weakref.ref(cfg))
api = getapi(cfg) api = getapi(cfg)
weakrefs.append(weakref.ref(api)) weakrefs.append(weakref.ref(api))
return api, weakrefs return api, weakrefs
@ -874,8 +995,8 @@ DICT_PATHS = [
('subod.subsubod.third', {'third': {'hidden': True}})]), ('subod.subsubod.third', {'third': {'hidden': True}})]),
#test a config with masterslaves #test a config with masterslaves
OrderedDict([('odmaster.first', {'odmaster': {'master': True}}), OrderedDict([('odmaster.first', {'odmaster': {'master': True}}),
('odmaster.second', {'second': {'disabled': True}}), ('odmaster.second', {'second': {'disabled': True, 'slave': True}}),
('odmaster.third', {'third': {'hidden': True}})]), ('odmaster.third', {'third': {'hidden': True, 'slave': True}})]),
##test a config with dynoption ##test a config with dynoption
OrderedDict([('subod.first', {'subod': {'dyn': True}}), OrderedDict([('subod.first', {'subod': {'dyn': True}}),
('subod.second', {'second': {'disabled': True}}), ('subod.second', {'second': {'disabled': True}}),
@ -940,21 +1061,24 @@ def test_options(paths):
return kwargs return kwargs
lpaths = list(paths.keys()) lpaths = list(paths.keys())
for multi in (False, True): for meta in (False, True):
api, weakrefs = make_api(paths, multi) for default_multi in (False, True):
if api is None: for default in (False, True):
continue for multi in (False, True, submulti):
if len(lpaths) == 9: if multi is False and default_multi:
check_all(api, lpaths[3], multi, **get_kwargs(lpaths[0])) continue
check_all(api, lpaths[4], multi, **get_kwargs(lpaths[1])) api, weakrefs = make_api(paths, meta, multi, default, default_multi)
check_all(api, lpaths[5], multi, **get_kwargs(lpaths[2])) if api is None:
check_all(api, lpaths[6], multi, **get_kwargs(lpaths[0])) continue
check_all(api, lpaths[7], multi, **get_kwargs(lpaths[1])) if len(lpaths) == 9:
check_all(api, lpaths[8], multi, **get_kwargs(lpaths[2])) check_all(api, lpaths[3], meta, multi, default, default_multi, **get_kwargs(lpaths[0]))
else: check_all(api, lpaths[4], meta, multi, default, default_multi, **get_kwargs(lpaths[1]))
check_all(api, lpaths[0], multi, **get_kwargs(lpaths[0])) check_all(api, lpaths[5], meta, multi, default, default_multi, **get_kwargs(lpaths[2]))
check_all(api, lpaths[1], multi, **get_kwargs(lpaths[1])) check_all(api, lpaths[6], meta, multi, default, default_multi, **get_kwargs(lpaths[0]))
check_all(api, lpaths[2], multi, **get_kwargs(lpaths[2])) check_all(api, lpaths[7], meta, multi, default, default_multi, **get_kwargs(lpaths[1]))
del(api) check_all(api, lpaths[8], meta, multi, default, default_multi, **get_kwargs(lpaths[2]))
for wr in weakrefs: else:
assert wr() is None for lpath in lpaths:
check_all(api, lpath, meta, multi, default, default_multi, **get_kwargs(lpath))
del api
check_deref(weakrefs)

View File

@ -12,7 +12,7 @@
# #
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from .config import Config from .config import Config, MetaConfig
from .option import * from .option import *
from .error import APIError from .error import APIError
from .api import getapi from .api import getapi
@ -20,7 +20,11 @@ from .option import __all__ as all_options
from .setting import owners, undefined from .setting import owners, undefined
allfuncs = ['Config', 'getapi', 'APIError', 'undefined'] allfuncs = ['MetaConfig',
'Config'
'getapi',
'APIError',
'undefined']
allfuncs.extend(all_options) allfuncs.extend(all_options)
del(all_options) del(all_options)
__all__ = tuple(allfuncs) __all__ = tuple(allfuncs)

View File

@ -24,7 +24,7 @@ except:
Multi = list Multi = list
class CommonTiramisu(object): class CommonTiramisuOption(object):
icon = '\u2937' icon = '\u2937'
tmpl_help = u' {} {}: {}' tmpl_help = u' {} {}: {}'
allow_unrestraint = False allow_unrestraint = False
@ -63,10 +63,10 @@ class CommonTiramisu(object):
if name == 'help': if name == 'help':
return self._help() return self._help()
else: else:
if not hasattr(CommonTiramisu, name): if not hasattr(CommonTiramisuOption, name):
raise APIError(_('unknown method {}').format(name)) raise APIError(_('unknown method {}').format(name))
else: else:
super(CommonTiramisu, self).__getattribute__(name) super(CommonTiramisuOption, self).__getattribute__(name)
def _help(self): def _help(self):
txt = [] txt = []
@ -78,7 +78,7 @@ class CommonTiramisu(object):
return '\n'.join(txt) return '\n'.join(txt)
class TiramisuOptionOption(CommonTiramisu): class TiramisuOptionOption(CommonTiramisuOption):
"""get information from an option""" """get information from an option"""
allow_unrestraint = True allow_unrestraint = True
slave_need_index = False slave_need_index = False
@ -105,6 +105,10 @@ class TiramisuOptionOption(CommonTiramisu):
"""test if option could have multi value""" """test if option could have multi value"""
return self.opt.impl_is_multi() return self.opt.impl_is_multi()
def issubmulti(self):
"""test if option could have submulti value"""
return self.opt.impl_is_submulti()
def ismasterslaves(self): def ismasterslaves(self):
"""test if option is a master or a slave""" """test if option is a master or a slave"""
return self.opt.impl_is_master_slaves() return self.opt.impl_is_master_slaves()
@ -123,8 +127,14 @@ class TiramisuOptionOption(CommonTiramisu):
def getdoc(self): def getdoc(self):
return self.opt.impl_get_display_name() return self.opt.impl_get_display_name()
def getdefault(self):
return self.opt.impl_getdefault()
class TiramisuOptionOwner(CommonTiramisu): def getdefaultmulti(self):
return self.opt.impl_getdefault_multi()
class TiramisuOptionOwner(CommonTiramisuOption):
"""manager option's owner""" """manager option's owner"""
def __init__(self, def __init__(self,
@ -170,7 +180,7 @@ class TiramisuOptionOwner(CommonTiramisu):
force_permissive=self.force_permissive) force_permissive=self.force_permissive)
class TiramisuOptionProperty(CommonTiramisu): class TiramisuOptionProperty(CommonTiramisuOption):
"""manager option's property""" """manager option's property"""
#allow_unrestraint = True #allow_unrestraint = True
slave_need_index = False slave_need_index = False
@ -212,7 +222,7 @@ class TiramisuOptionProperty(CommonTiramisu):
self.settings.reset(_path=self.path) self.settings.reset(_path=self.path)
class TiramisuOptionPermissive(CommonTiramisu): class TiramisuOptionPermissive(CommonTiramisuOption):
"""manager option's property""" """manager option's property"""
allow_unrestraint = True allow_unrestraint = True
slave_need_index = False slave_need_index = False
@ -249,8 +259,9 @@ class TiramisuOptionPermissive(CommonTiramisu):
# self.settings.reset(_path=path) # self.settings.reset(_path=path)
class TiramisuOptionValue(CommonTiramisu): class TiramisuOptionValue(CommonTiramisuOption):
"""manager option's value""" """manager option's value"""
slave_need_index = False
def __init__(self, def __init__(self,
opt, opt,
@ -270,6 +281,7 @@ class TiramisuOptionValue(CommonTiramisu):
force_unrestraint) force_unrestraint)
def get(self): def get(self):
self._test_slave_index()
settings = self.config.cfgimpl_get_settings() settings = self.config.cfgimpl_get_settings()
value = self.config.getattr(self.path, value = self.config.getattr(self.path,
index=self.index, index=self.index,
@ -281,6 +293,7 @@ class TiramisuOptionValue(CommonTiramisu):
def set(self, value): def set(self, value):
"""set a value for a specified option""" """set a value for a specified option"""
self._test_slave_index()
values = self.config.cfgimpl_get_values() values = self.config.cfgimpl_get_values()
if isinstance(value, list): if isinstance(value, list):
while undefined in value: while undefined in value:
@ -301,6 +314,8 @@ class TiramisuOptionValue(CommonTiramisu):
def pop(self, index): def pop(self, index):
"""pop value for a specified master values """pop value for a specified master values
""" """
self._test_slave_index()
#FIXME only for master
self.config.delattr(self.path, self.config.delattr(self.path,
index=index, index=index,
setting_properties=self.setting_properties, setting_properties=self.setting_properties,
@ -308,11 +323,20 @@ class TiramisuOptionValue(CommonTiramisu):
def reset(self): def reset(self):
"""reset value for a value""" """reset value for a value"""
self._test_slave_index()
self.config.delattr(self.path, self.config.delattr(self.path,
index=self.index, index=self.index,
setting_properties=self.setting_properties, setting_properties=self.setting_properties,
force_permissive=self.force_permissive) force_permissive=self.force_permissive)
def len(self):
#FIXME only for slave
subconfig_path = self.path.rsplit('.', 1)[0]
subconfig = self.config.getattr(subconfig_path,
setting_properties=self.setting_properties,
force_permissive=self.force_permissive)
return subconfig.cfgimpl_get_length()
class TiramisuOption(object): class TiramisuOption(object):
icon = '\u2937' icon = '\u2937'
@ -365,6 +389,15 @@ class TiramisuOption(object):
raise APIError(_('please specify a valid sub function')) raise APIError(_('please specify a valid sub function'))
class TiramisuContext(object):
def __init__(self, config):
self.config = config
class TiramisuContextOwner(TiramisuContext):
def get(self):
return self.config.cfgimpl_get_settings().getowner()
class TiramisuAPI(object): class TiramisuAPI(object):
icon = '\u2937' icon = '\u2937'
tmpl_help = ' {} {}: {}' tmpl_help = ' {} {}: {}'
@ -385,7 +418,7 @@ class TiramisuAPI(object):
def option(self, path, index=None): def option(self, path, index=None):
validate = not self.force_unrestraint validate = not self.force_unrestraint
settings = self.config.cfgimpl_get_settings() settings = self.config.cfgimpl_get_settings()
setting_properties = settings.get_global_properties() setting_properties = settings.get_context_properties()
if validate: if validate:
s_properties = setting_properties s_properties = setting_properties
else: else:
@ -406,6 +439,7 @@ class TiramisuAPI(object):
self.force_permissive, self.force_permissive,
self.force_unrestraint) self.force_unrestraint)
def __getattr__(self, subfunc): def __getattr__(self, subfunc):
if subfunc == 'forcepermissive': if subfunc == 'forcepermissive':
return TiramisuAPI(self.config, return TiramisuAPI(self.config,
@ -417,6 +451,8 @@ class TiramisuAPI(object):
force_unrestraint=True) force_unrestraint=True)
elif subfunc == 'help': elif subfunc == 'help':
return self._help() return self._help()
elif subfunc == 'owner':
return TiramisuContextOwner(self.config)
else: else:
raise APIError(_('please specify a valid sub function')) raise APIError(_('please specify a valid sub function'))

View File

@ -87,6 +87,9 @@ class SubConfig(object):
validate=validate, validate=validate,
force_permissive=force_permissive) force_permissive=force_permissive)
def cfgimpl_get_length(self):
return self._impl_length
def reset_one_option_cache(self, values, settings, resetted_opts, opt, only): def reset_one_option_cache(self, values, settings, resetted_opts, opt, only):
if 'values' in only: if 'values' in only:
tresetted_opts = copy(resetted_opts) tresetted_opts = copy(resetted_opts)
@ -401,7 +404,7 @@ class SubConfig(object):
raise ret raise ret
def __getattr__(self, name): def __getattr__(self, name):
setting_properties = self.cfgimpl_get_context().cfgimpl_get_settings().get_global_properties() setting_properties = self.cfgimpl_get_context().cfgimpl_get_settings().get_context_properties()
return self.getattr(name, setting_properties) return self.getattr(name, setting_properties)
def _get_subpath(self, name): def _get_subpath(self, name):
@ -480,9 +483,15 @@ class SubConfig(object):
subpath) subpath)
else: else:
if validate: if validate:
ret = self.cfgimpl_get_description().impl_validate(context, self.cfgimpl_get_description().impl_validate(context,
force_permissive, force_permissive,
setting_properties) setting_properties)
if option.impl_is_master_slaves('slave') and index is not None and \
index >= self._impl_length:
raise IndexError(_('index ({}) is higher than the master length ({}) for "{}"'
'').format(index,
self._impl_length,
subpath))
cfg = self.cfgimpl_get_values().get_cached_value(option, cfg = self.cfgimpl_get_values().get_cached_value(option,
path=subpath, path=subpath,
validate=validate, validate=validate,
@ -859,9 +868,14 @@ class Config(_CommonConfig):
"main configuration management entry" "main configuration management entry"
__slots__ = ('__weakref__', '_impl_test', '_impl_name') __slots__ = ('__weakref__', '_impl_test', '_impl_name')
def __init__(self, descr, session_id=None, persistent=False, def __init__(self,
force_values=None, force_settings=None, descr,
_duplicate=False, _force_store_values=True): session_id=None,
persistent=False,
force_values=None,
force_settings=None,
_duplicate=False,
_force_store_values=True):
""" Configuration option management master class """ Configuration option management master class
:param descr: describes the configuration schema :param descr: describes the configuration schema
@ -876,17 +890,29 @@ class Config(_CommonConfig):
""" """
if force_settings is not None and force_values is not None: if force_settings is not None and force_values is not None:
if isinstance(force_settings, tuple): if isinstance(force_settings, tuple):
self._impl_settings = Settings(self, force_settings[0], force_settings[1]) self._impl_settings = Settings(self,
force_settings[0],
force_settings[1])
else: else:
self._impl_settings = force_settings self._impl_settings = force_settings
self._impl_values = Values(self, force_values) self._impl_values = Values(self,
force_values)
else: else:
properties, permissives, values, session_id = get_storages(self, session_id, persistent) properties, permissives, values, session_id = get_storages(self,
session_id,
persistent)
if not valid_name(session_id): # pragma: optional cover if not valid_name(session_id): # pragma: optional cover
raise ValueError(_("invalid session ID: {0} for config").format(session_id)) raise ValueError(_("invalid session ID: {0} for config").format(session_id))
self._impl_settings = Settings(self, properties, permissives) self._impl_settings = Settings(self,
self._impl_values = Values(self, values) properties,
super(Config, self).__init__(descr, weakref.ref(self), undefined, True, False) permissives)
self._impl_values = Values(self,
values)
super(Config, self).__init__(descr,
weakref.ref(self),
undefined,
True,
False)
self._impl_meta = None self._impl_meta = None
#undocumented option used only in test script #undocumented option used only in test script
self._impl_test = False self._impl_test = False
@ -902,15 +928,21 @@ class Config(_CommonConfig):
class GroupConfig(_CommonConfig): class GroupConfig(_CommonConfig):
__slots__ = ('__weakref__', '_impl_children', '_impl_name') __slots__ = ('__weakref__',
'_impl_children',
'_impl_name')
def __init__(self, children, session_id=None, persistent=False, def __init__(self,
children,
session_id=None,
persistent=False,
_descr=None): _descr=None):
if not isinstance(children, list): if not isinstance(children, list):
raise ValueError(_("groupconfig's children must be a list")) raise ValueError(_("groupconfig's children must be a list"))
names = [] names = []
for child in children: for child in children:
if not isinstance(child, _CommonConfig): if not isinstance(child,
_CommonConfig):
raise ValueError(_("groupconfig's children must be Config, MetaConfig or GroupConfig")) raise ValueError(_("groupconfig's children must be Config, MetaConfig or GroupConfig"))
name_ = child._impl_name name_ = child._impl_name
names.append(name_) names.append(name_)
@ -921,10 +953,18 @@ class GroupConfig(_CommonConfig):
raise ConflictError(_('config name must be uniq in ' raise ConflictError(_('config name must be uniq in '
'groupconfig for {0}').format(name)) 'groupconfig for {0}').format(name))
self._impl_children = children self._impl_children = children
properties, permissives, values, session_id = get_storages(self, session_id, persistent) properties, permissives, values, session_id = get_storages(self,
self._impl_settings = Settings(self, properties, permissives) session_id,
persistent)
self._impl_settings = Settings(self,
properties,
permissives)
self._impl_values = Values(self, values) self._impl_values = Values(self, values)
super(GroupConfig, self).__init__(_descr, weakref.ref(self)) super(GroupConfig, self).__init__(_descr,
weakref.ref(self),
undefined,
True,
False)
self._impl_meta = None self._impl_meta = None
#undocumented option used only in test script #undocumented option used only in test script
self._impl_test = False self._impl_test = False
@ -958,11 +998,19 @@ class GroupConfig(_CommonConfig):
ret = [] ret = []
for child in self._impl_children: for child in self._impl_children:
if isinstance(child, MetaConfig): if isinstance(child, MetaConfig):
ret.extend(child.set_value(path, value, only_config=True, _commit=False)) ret.extend(child.set_value(path,
value,
only_config=True,
_commit=False))
elif isinstance(child, GroupConfig): elif isinstance(child, GroupConfig):
ret.extend(child.set_value(path, value, _commit=False)) ret.extend(child.set_value(path,
value,
_commit=False))
else: else:
childret = child.setattr(path, value, not_raises=True, _commit=False) childret = child.setattr(path,
value,
not_raises=True,
_commit=False)
if childret is not None: if childret is not None:
ret.append(childret) ret.append(childret)
if _commit: if _commit:
@ -970,8 +1018,13 @@ class GroupConfig(_CommonConfig):
return ret return ret
def find_firsts(self, byname=None, bypath=undefined, byoption=undefined, def find_firsts(self,
byvalue=undefined, raise_if_not_found=True, _sub=False, byname=None,
bypath=undefined,
byoption=undefined,
byvalue=undefined,
raise_if_not_found=True,
_sub=False,
check_properties=True): check_properties=True):
"""Find first not in current GroupConfig, but in each children """Find first not in current GroupConfig, but in each children
""" """
@ -980,32 +1033,42 @@ class GroupConfig(_CommonConfig):
#if MetaConfig, all children have same OptionDescription in context #if MetaConfig, all children have same OptionDescription in context
#so search only one time the option for all children #so search only one time the option for all children
if bypath is undefined and byname is not None and \ if bypath is undefined and byname is not None and \
isinstance(self, MetaConfig): isinstance(self,
bypath = self._find(bytype=None, byvalue=undefined, byname=byname, MetaConfig):
first=True, type_='path', bypath = self._find(bytype=None,
byvalue=undefined,
byname=byname,
first=True,
type_='path',
check_properties=None, check_properties=None,
raise_if_not_found=raise_if_not_found) raise_if_not_found=raise_if_not_found)
byname = None byname = None
byoption = self.cfgimpl_get_description( byoption = self.cfgimpl_get_description().impl_get_opt_by_path(bypath)
).impl_get_opt_by_path(bypath)
for child in self._impl_children: for child in self._impl_children:
if isinstance(child, GroupConfig): if isinstance(child, GroupConfig):
ret.extend(child.find_firsts(byname=byname, bypath=bypath, ret.extend(child.find_firsts(byname=byname,
bypath=bypath,
byoption=byoption, byoption=byoption,
byvalue=byvalue, byvalue=byvalue,
check_properties=check_properties, check_properties=check_properties,
raise_if_not_found=False, raise_if_not_found=False,
_sub=True)) _sub=True))
elif child._find(None, byname, byvalue, first=True, elif child._find(None,
type_='path', raise_if_not_found=False, byname,
byvalue,
first=True,
type_='path',
raise_if_not_found=False,
check_properties=check_properties, check_properties=check_properties,
only_path=bypath, only_option=byoption): only_path=bypath,
only_option=byoption):
ret.append(child) ret.append(child)
if _sub: if _sub:
return ret return ret
else: else:
return GroupConfig(self._find_return_results(ret, raise_if_not_found)) return GroupConfig(self._find_return_results(ret,
raise_if_not_found))
def __str__(self): def __str__(self):
ret = '' ret = ''
@ -1022,32 +1085,38 @@ class GroupConfig(_CommonConfig):
setting_properties, setting_properties,
force_permissive=False, force_permissive=False,
validate=True, validate=True,
index=None,
validate_properties=True, validate_properties=True,
index=None,
returns_option=False): returns_option=False):
for child in self._impl_children: for child in self._impl_children:
if name == child._impl_name: if name == child.impl_getname():
return child return child
return super(GroupConfig, self).getattr(name, force_permissive, return super(GroupConfig, self).getattr(name,
setting_properties,
force_permissive,
validate, validate,
index=index,
setting_properties=setting_properties,
validate_properties=validate_properties, validate_properties=validate_properties,
returns_option=False) index=index,
returns_option=returns_option)
class MetaConfig(GroupConfig): class MetaConfig(GroupConfig):
__slots__ = tuple() __slots__ = tuple()
def __init__(self, children, session_id=None, persistent=False, def __init__(self,
optiondescription=None, _force_store_values=True): children,
session_id=None,
persistent=False,
optiondescription=None,
_force_store_values=True):
descr = None descr = None
if optiondescription is not None: if optiondescription is not None:
new_children = [] new_children = []
for child_session_id in children: for child_session_id in children:
#FIXME _force_store_values doit etre a true si inexistant ! new_children.append(Config(optiondescription,
new_children.append(Config(optiondescription, persistent=persistent, persistent=persistent,
session_id=child_session_id, _force_store_values=_force_store_values)) session_id=child_session_id,
_force_store_values=_force_store_values))
children = new_children children = new_children
for child in children: for child in children:
if not isinstance(child, _CommonConfig): if not isinstance(child, _CommonConfig):
@ -1063,12 +1132,19 @@ class MetaConfig(GroupConfig):
'have the same optiondescription')) 'have the same optiondescription'))
child._impl_meta = weakref.ref(self) child._impl_meta = weakref.ref(self)
super(MetaConfig, self).__init__(children, session_id, persistent, super(MetaConfig, self).__init__(children,
session_id,
persistent,
descr) descr)
def set_value(self, path, value, force_default=False, def set_value(self,
force_dont_change_value=False, force_default_if_same=False, path,
only_config=False, _commit=True): value,
force_default=False,
force_dont_change_value=False,
force_default_if_same=False,
only_config=False,
_commit=True):
"""only_config: could be set if you want modify value in all Config included in """only_config: could be set if you want modify value in all Config included in
this MetaConfig this MetaConfig
""" """
@ -1077,7 +1153,9 @@ class MetaConfig(GroupConfig):
raise ValueError(_('force_default, force_default_if_same or ' raise ValueError(_('force_default, force_default_if_same or '
'force_dont_change_value cannot be set with' 'force_dont_change_value cannot be set with'
' only_config')) ' only_config'))
return super(MetaConfig, self).set_value(path, value, _commit=_commit) return super(MetaConfig, self).set_value(path,
value,
_commit=_commit)
ret = [] ret = []
if force_default or force_default_if_same or force_dont_change_value: if force_default or force_default_if_same or force_dont_change_value:
if force_default and force_dont_change_value: if force_default and force_dont_change_value:
@ -1134,8 +1212,11 @@ class MetaConfig(GroupConfig):
setting_properties, setting_properties,
validate=False) validate=False)
def new_config(self, session_id, persistent=False): def new_config(self,
config = Config(self._impl_descr, session_id=session_id, session_id,
persistent=False):
config = Config(self._impl_descr,
session_id=session_id,
persistent=persistent) persistent=persistent)
if config._impl_name in [child._impl_name for child in self._impl_children]: # pragma: no cover if config._impl_name in [child._impl_name for child in self._impl_children]: # pragma: no cover

View File

@ -369,7 +369,7 @@ class Settings(object):
return Property(self, properties, opt, path) return Property(self, properties, opt, path)
return properties return properties
def get_global_properties(self): def get_context_properties(self):
return self._getproperties() return self._getproperties()
def __setitem__(self, opt, value): # pragma: optional cover def __setitem__(self, opt, value): # pragma: optional cover