find in api return an api object

This commit is contained in:
Emmanuel Garette 2018-04-10 12:33:51 +02:00
parent 9ea373efdf
commit 5eb2f04202
13 changed files with 280 additions and 267 deletions

View file

@ -1074,6 +1074,7 @@ def autocheck_option_get(api, pathread, pathwrite, confread, confwrite, **kwargs
@autocheck @autocheck
def autocheck_find(api, pathread, pathwrite, confread, confwrite, **kwargs): def autocheck_find(api, pathread, pathwrite, confread, confwrite, **kwargs):
def _getoption(opt): def _getoption(opt):
opt = opt.option.get()
if opt.impl_is_dynsymlinkoption(): if opt.impl_is_dynsymlinkoption():
opt = opt.impl_getopt() opt = opt.impl_getopt()
return opt return opt
@ -1088,7 +1089,7 @@ def autocheck_find(api, pathread, pathwrite, confread, confwrite, **kwargs):
name = pathread.rsplit('.', 1)[1] name = pathread.rsplit('.', 1)[1]
else: else:
name = pathread name = pathread
option = _getoption(api.unrestraint.option(pathread).option.get()) option = _getoption(api.unrestraint.option(pathread))
def do(conf): def do(conf):
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False): if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
@ -1102,8 +1103,6 @@ def autocheck_find(api, pathread, pathwrite, confread, confwrite, **kwargs):
raises(AttributeError, "api.forcepermissive.config(conf).option.find(name, first=True)") raises(AttributeError, "api.forcepermissive.config(conf).option.find(name, first=True)")
assert option == _getoption(api.unrestraint.config(conf).option.find(name, first=True)) assert option == _getoption(api.unrestraint.config(conf).option.find(name, first=True))
assert [option] == _getoptions(api.unrestraint.config(conf).option.find(name)) assert [option] == _getoptions(api.unrestraint.config(conf).option.find(name))
assert pathread == api.unrestraint.config(conf).option.find(name, 'path', first=True)
assert [pathread] == api.unrestraint.config(conf).option.find(name, 'path')
do(confread) do(confread)
if confread != confwrite: if confread != confwrite:
do(confwrite) do(confwrite)

View file

@ -14,8 +14,8 @@ from tiramisu.error import PropertiesOptionError
def make_description(): def make_description():
gcoption = ChoiceOption('name', 'GC name', ('ref', 'framework'), 'ref') gcoption = ChoiceOption('name', 'GC name', ('ref', 'framework'), 'ref')
gcdummy = BoolOption('dummy', 'dummy', default=False) gcdummy = BoolOption('dummy', 'dummy', default=False)
prop = BoolOption('prop', '', properties=('disabled',)) prop = BoolOption('prop', 'prop 1', properties=('disabled',))
prop2 = BoolOption('prop', '', properties=('hidden',)) prop2 = BoolOption('prop', 'prop 2', properties=('hidden',))
objspaceoption = ChoiceOption('objspace', 'Object space', objspaceoption = ChoiceOption('objspace', 'Object space',
('std', 'thunk'), 'std') ('std', 'thunk'), 'std')
booloption = BoolOption('bool', 'Test boolean option', default=True) booloption = BoolOption('bool', 'Test boolean option', default=True)
@ -165,96 +165,111 @@ def test_find_in_config():
api.permissive.set(frozenset(['hidden'])) api.permissive.set(frozenset(['hidden']))
ret = api.option.find('dummy') ret = api.option.find('dummy')
assert len(ret) == 1 assert len(ret) == 1
_is_same_opt(ret[0], api.option('gc.dummy').option.get()) _is_same_opt(ret[0].option.get(), api.option('gc.dummy').option.get())
# #
ret = api.option.find('dummy', first=True) ret = api.option.find('dummy', first=True).option.get()
_is_same_opt(ret, api.option('gc.dummy').option.get()) _is_same_opt(ret, api.option('gc.dummy').option.get())
# #
ret = api.option.find('float') ret = api.option.find('float')
assert len(ret) == 2 assert len(ret) == 2
_is_same_opt(ret[0], api.option('gc.float').option.get()) _is_same_opt(ret[0].option.get(), api.option('gc.float').option.get())
_is_same_opt(ret[1], api.option('float').option.get()) _is_same_opt(ret[1].option.get(), api.option('float').option.get())
# #
_is_same_opt(api.option.find('bool', first=True), api.option('gc.gc2.bool').option.get()) _is_same_opt(api.option.find('bool', first=True).option.get(), api.option('gc.gc2.bool').option.get())
#_is_same_opt(conf.find_first(byname='bool', byvalue=True), conf.unwrap_from_path('bool')) _is_same_opt(api.option.find('bool', value=True, first=True).option.get(), api.option('bool').option.get())
#_is_same_opt(conf.find_first(byname='dummy'), conf.unwrap_from_path('gc.dummy')) _is_same_opt(api.option.find('dummy', first=True).option.get(), api.option('gc.dummy').option.get())
#_is_same_opt(conf.find_first(byname='float'), conf.unwrap_from_path('gc.float')) _is_same_opt(api.option.find('float', first=True).option.get(), api.option('gc.float').option.get())
#FIXME cannot find an option without name
#ret = conf.find(bytype=ChoiceOption) #ret = conf.find(bytype=ChoiceOption)
#assert len(ret) == 2 #assert len(ret) == 2
#_is_same_opt(ret[0], conf.unwrap_from_path('gc.name')) #_is_same_opt(ret[0], conf.unwrap_from_path('gc.name'))
#_is_same_opt(ret[1], conf.unwrap_from_path('objspace')) #_is_same_opt(ret[1], conf.unwrap_from_path('objspace'))
#
#_is_same_opt(conf.find_first(bytype=ChoiceOption), conf.unwrap_from_path('gc.name')) #_is_same_opt(conf.find_first(bytype=ChoiceOption), conf.unwrap_from_path('gc.name'))
#ret = conf.find(byvalue='ref') #ret = conf.find(byvalue='ref')
#assert len(ret) == 1 #assert len(ret) == 1
#_is_same_opt(ret[0], conf.unwrap_from_path('gc.name')) #_is_same_opt(ret[0], conf.unwrap_from_path('gc.name'))
#_is_same_opt(conf.find_first(byvalue='ref'), conf.unwrap_from_path('gc.name')) #_is_same_opt(conf.find_first(byvalue='ref'), conf.unwrap_from_path('gc.name'))
#ret = conf.find(byname='prop') #
#assert len(ret) == 1 ret = api.option.find('prop')
#_is_same_opt(ret[0], conf.unwrap_from_path('gc.prop')) assert len(ret) == 1
#conf.read_write() _is_same_opt(ret[0].option.get(), api.option('gc.prop').option.get())
#raises(AttributeError, "assert conf.find(byname='prop')") #
#ret = conf.find(byname='prop', check_properties=False) api.property.read_write()
#assert len(ret) == 2 raises(AttributeError, "assert api.option.find('prop').option.get()")
#_is_same_opt(ret[0], conf.cfgimpl_get_description().impl_get_opt_by_path('gc.gc2.prop')) ret = api.unrestraint.option.find(name='prop')
#_is_same_opt(ret[1], conf.unwrap_from_path('gc.prop', force_permissive=True)) assert len(ret) == 2
#ret = conf.find(byname='prop', force_permissive=True) _is_same_opt(ret[0].option.get(), api.unrestraint.option('gc.gc2.prop').option.get())
#assert len(ret) == 1 _is_same_opt(ret[1].option.get(), api.forcepermissive.option('gc.prop').option.get())
#_is_same_opt(ret[0], conf.unwrap_from_path('gc.prop', force_permissive=True)) #
#_is_same_opt(conf.find_first(byname='prop', force_permissive=True), conf.unwrap_from_path('gc.prop', force_permissive=True)) ret = api.forcepermissive.option.find('prop')
##assert conf.find_first(byname='prop') == conf.unwrap_from_path('gc.prop') assert len(ret) == 1
## combinaison of filters _is_same_opt(ret[0].option.get(), api.forcepermissive.option('gc.prop').option.get())
#
_is_same_opt(api.forcepermissive.option.find('prop', first=True).option.get(), api.forcepermissive.option('gc.prop').option.get())
#FIXME cannot find an option without name
# combinaison of filters
#ret = conf.find(bytype=BoolOption, byname='dummy') #ret = conf.find(bytype=BoolOption, byname='dummy')
#assert len(ret) == 1 #assert len(ret) == 1
#_is_same_opt(ret[0], conf.unwrap_from_path('gc.dummy')) #_is_same_opt(ret[0], conf.unwrap_from_path('gc.dummy'))
#_is_same_opt(conf.find_first(bytype=BoolOption, byname='dummy'), conf.unwrap_from_path('gc.dummy')) #_is_same_opt(conf.find_first(bytype=BoolOption, byname='dummy'), conf.unwrap_from_path('gc.dummy'))
#ret = conf.find(byvalue=False, byname='dummy') #
#assert len(ret) == 1 ret = api.option.find('dummy', value=False)
#_is_same_opt(ret[0], conf.unwrap_from_path('gc.dummy')) assert len(ret) == 1
#_is_same_opt(conf.find_first(byvalue=False, byname='dummy'), conf.unwrap_from_path('gc.dummy')) _is_same_opt(ret[0].option.get(), api.option('gc.dummy').option.get())
##subconfig #
#ret = conf.gc.find(byname='dummy') _is_same_opt(api.option.find('dummy', value=False, first=True).option.get(), api.option('gc.dummy').option.get())
#assert len(ret) == 1 #subconfig
#_is_same_opt(ret[0], conf.unwrap_from_path('gc.dummy')) ret = api.option('gc').find('dummy')
#ret = conf.gc.find(byname='float') assert len(ret) == 1
#assert len(ret) == 1 _is_same_opt(ret[0].option.get(), api.option('gc.dummy').option.get())
#_is_same_opt(ret[0], conf.unwrap_from_path('gc.float')) #
#ret = conf.gc.find(byname='bool') ret = api.option('gc').find('float')
#assert len(ret) == 1 assert len(ret) == 1
#_is_same_opt(ret[0], conf.unwrap_from_path('gc.gc2.bool')) _is_same_opt(ret[0].option.get(), api.option('gc.float').option.get())
#_is_same_opt(conf.gc.find_first(byname='bool', byvalue=False), conf.unwrap_from_path('gc.gc2.bool')) #
#raises(AttributeError, "assert conf.gc.find_first(byname='bool', byvalue=True)") ret = api.option('gc').find('bool')
#raises(AttributeError, "conf.gc.find(byname='wantref').first()") assert len(ret) == 1
#ret = conf.gc.find(byname='prop', check_properties=False) _is_same_opt(ret[0].option.get(), api.option('gc.gc2.bool').option.get())
#assert len(ret) == 2 _is_same_opt(api.option('gc').find('bool', value=False, first=True).option.get(), api.option('gc.gc2.bool').option.get())
#_is_same_opt(ret[0], conf.cfgimpl_get_description().impl_get_opt_by_path('gc.gc2.prop')) #
#_is_same_opt(ret[1], conf.unwrap_from_path('gc.prop', force_permissive=True)) raises(AttributeError, "assert api.option('gc').find('bool', value=True, first=True).option.get()")
#conf.read_only() #
#ret = conf.gc.find(byname='prop') raises(AttributeError, "api.option('gc').find('wantref').option.get()")
#assert len(ret) == 1 #
#_is_same_opt(ret[0], conf.unwrap_from_path('gc.prop')) ret = api.unrestraint.option('gc').find('prop')
## not OptionDescription assert len(ret) == 2
#raises(AttributeError, "conf.find_first(byname='gc')") _is_same_opt(ret[0].option.get(), api.unrestraint.option('gc.gc2.prop').option.get())
#raises(AttributeError, "conf.gc.find_first(byname='gc2')") _is_same_opt(ret[1].option.get(), api.forcepermissive.option('gc.prop').option.get())
#raises(ValueError, "conf.find(byname='bool', type_='unknown')") #
api.property.read_only()
ret = api.option('gc').find('prop')
assert len(ret) == 1
_is_same_opt(ret[0].option.get(), api.option('gc.prop').option.get())
# not OptionDescription
raises(AttributeError, "api.option.find('gc', first=True)")
raises(AttributeError, "api.option.find('gc2', first=True)")
#def test_find_multi(): def test_find_multi():
# b = BoolOption('bool', '', multi=True) b = BoolOption('bool', '', multi=True)
# o = OptionDescription('od', '', [b]) o = OptionDescription('od', '', [b])
# conf = Config(o) conf = Config(o)
# raises(AttributeError, "conf.find(byvalue=True)") api = getapi(conf)
# raises(AttributeError, "conf.find_first(byvalue=True)") #
# conf.bool.append(False) raises(AttributeError, "api.option.find('bool', value=True)")
# raises(AttributeError, "conf.find(byvalue=True)") raises(AttributeError, "api.option.find('bool', value=True, first=True)")
# raises(AttributeError, "conf.find_first(byvalue=True)") api.option('bool').value.set([False])
# conf.bool.append(False) raises(AttributeError, "api.option.find('bool', value=True)")
# raises(AttributeError, "conf.find(byvalue=True)") raises(AttributeError, "api.option.find('bool', value=True, first=True)")
# raises(AttributeError, "conf.find_first(byvalue=True)") api.option('bool').value.set([False, False])
# conf.bool.append(True) raises(AttributeError, "api.option.find('bool', value=True)")
# ret = conf.find(byvalue=True) raises(AttributeError, "api.option.find('bool', value=True, first=True)")
# assert len(ret) == 1 api.option('bool').value.set([False, False, True])
# _is_same_opt(ret[0], b) ret = api.option.find('bool', value=True)
# _is_same_opt(conf.find_first(byvalue=True), b) assert len(ret) == 1
_is_same_opt(ret[0].option.get(), b)
_is_same_opt(api.option.find('bool', value=True, first=True).option.get(), b)
def test_does_not_find_in_config(): def test_does_not_find_in_config():

View file

@ -36,7 +36,7 @@ def return_list(val=None, suffix=None):
return ['val1', 'val2'] return ['val1', 'val2']
def return_same_list(suffix): def return_same_list(*args, **kwargs):
return ['val1', 'val1'] return ['val1', 'val1']
@ -48,6 +48,10 @@ def return_raise(suffix):
raise Exception('error') raise Exception('error')
def return_str(*args, **kwargs):
return 'str'
def test_build_dyndescription(): def test_build_dyndescription():
st1 = StrOption('st', '') st1 = StrOption('st', '')
dod = DynOptionDescription('dod', '', [st1], callback=return_list) dod = DynOptionDescription('dod', '', [st1], callback=return_list)
@ -66,6 +70,15 @@ def test_build_dyndescription_raise():
raises(ConfigError, "api.option.make_dict()") raises(ConfigError, "api.option.make_dict()")
def test_build_dyndescription_not_list():
st1 = StrOption('st', '')
dod = DynOptionDescription('dod', '', [st1], callback=return_str)
od1 = OptionDescription('od', '', [dod])
cfg = Config(od1)
api = getapi(cfg)
raises(ValueError, "api.option.make_dict()")
def test_subpath_dyndescription(): def test_subpath_dyndescription():
st1 = StrOption('st', '') st1 = StrOption('st', '')
dod = DynOptionDescription('dod', '', [st1], callback=return_list) dod = DynOptionDescription('dod', '', [st1], callback=return_list)
@ -492,9 +505,7 @@ def test_requires_dyndescription():
assert api.option('od.dodval1.stval1').value.get() is None assert api.option('od.dodval1.stval1').value.get() is None
assert api.option('od.dodval2.stval2').value.get() is None assert api.option('od.dodval2.stval2').value.get() is None
# #
print('-----------------')
api.option('boolean').value.set(False) api.option('boolean').value.set(False)
print('-----------------')
props = [] props = []
try: try:
api.option('od.dodval1.stval1').value.get() api.option('od.dodval1.stval1').value.get()
@ -608,8 +619,8 @@ def test_find_dyndescription_context():
od2 = OptionDescription('od', '', [od]) od2 = OptionDescription('od', '', [od])
api = getapi(Config(od2)) api = getapi(Config(od2))
api.option('od.dodval1.stval1').value.set('yes') api.option('od.dodval1.stval1').value.set('yes')
assert api.option.find('stval1', type='value', first=True) == "yes" assert api.option.find('stval1', first=True).value.get() == "yes"
assert isinstance(api.option.find('stval1', type='option', first=True), DynSymLinkOption) assert isinstance(api.option.find('stval1', first=True).option.get(), DynSymLinkOption)
#assert api.option.find(bytype=StrOption, type='path') == ['od.dodval1.stval1', 'od.dodval2.stval2', 'od.val1'] #assert api.option.find(bytype=StrOption, type='path') == ['od.dodval1.stval1', 'od.dodval2.stval2', 'od.val1']
#opts = api.option.find(byvalue='yes') #opts = api.option.find(byvalue='yes')
#assert len(opts) == 1 #assert len(opts) == 1
@ -1185,7 +1196,7 @@ def test_invalid_samevalue_dyndescription():
od1 = OptionDescription('od', '', [dod]) od1 = OptionDescription('od', '', [dod])
cfg = Config(od1) cfg = Config(od1)
api = getapi(cfg) api = getapi(cfg)
raises(ConfigError, "api.option.make_dict()") raises(ValueError, "api.option.make_dict()")
def test_invalid_name_dyndescription(): def test_invalid_name_dyndescription():

View file

@ -52,7 +52,7 @@ def test_base_config():
api.property.read_write() api.property.read_write()
assert api.option('creole.general.activer_proxy_client').value.get() is False assert api.option('creole.general.activer_proxy_client').value.get() is False
assert api.option('creole.general.nom_machine').value.get() == "eoleng" assert api.option('creole.general.nom_machine').value.get() == "eoleng"
assert api.option.find('nom_machine', type='value', first=True) == "eoleng" assert api.option.find('nom_machine', first=True).value.get() == "eoleng"
result = {'general.numero_etab': None, 'general.nombre_interfaces': 1, result = {'general.numero_etab': None, 'general.nombre_interfaces': 1,
'general.serveur_ntp': [], 'interface1.ip_admin_eth0.ip_admin_eth0': None, 'general.serveur_ntp': [], 'interface1.ip_admin_eth0.ip_admin_eth0': None,
'general.mode_conteneur_actif': False, 'general.time_zone': 'Paris', 'general.mode_conteneur_actif': False, 'general.time_zone': 'Paris',

View file

@ -126,8 +126,10 @@ def test_contexts():
def test_find(): def test_find():
api = make_metaconfig() api = make_metaconfig()
assert [1] == api.option.find('i2', type='value') ret = api.option.find('i2')
assert 1 == api.option.find('i2', type='value', first=True) assert len(ret) == 1
assert 1 == ret[0].value.get()
assert 1 == api.option.find('i2', first=True).value.get()
assert api.option.make_dict() == {'od1.i4': 2, 'od1.i1': None, 'od1.i3': None, assert api.option.make_dict() == {'od1.i4': 2, 'od1.i1': None, 'od1.i3': None,
'od1.i2': 1, 'od1.i5': [2]} 'od1.i2': 1, 'od1.i5': [2]}
@ -203,14 +205,14 @@ def test_meta_meta_set():
conf1 = meta.getconfig('conf1') conf1 = meta.getconfig('conf1')
conf2 = meta.getconfig('conf2') conf2 = meta.getconfig('conf2')
assert api.config('meta.conf1').option('od1.i1').value.get() == api.config('meta.conf2').option('od1.i1').value.get() == 7 assert api.config('meta.conf1').option('od1.i1').value.get() == api.config('meta.conf2').option('od1.i1').value.get() == 7
assert [conf1, conf2] == api.config.find('i1', byvalue=7, first=True).cfgimpl_get_children() assert [conf1, conf2] == api.config.find('i1', value=7, first=True).cfgimpl_get_children()
api.config('meta.conf1').option('od1.i1').value.set(8) api.config('meta.conf1').option('od1.i1').value.set(8)
assert [conf1, conf2] == api.config.find('i1', first=True).cfgimpl_get_children() assert [conf1, conf2] == api.config.find('i1', first=True).cfgimpl_get_children()
assert [conf2] == api.config.find('i1', byvalue=7, first=True).cfgimpl_get_children() assert [conf2] == api.config.find('i1', value=7, first=True).cfgimpl_get_children()
assert [conf1] == api.config.find('i1', byvalue=8, first=True).cfgimpl_get_children() assert [conf1] == api.config.find('i1', value=8, first=True).cfgimpl_get_children()
assert [conf1, conf2] == api.config.find('i5', byvalue=2, first=True).cfgimpl_get_children() assert [conf1, conf2] == api.config.find('i5', value=2, first=True).cfgimpl_get_children()
raises(AttributeError, "api.config.find('i1', byvalue=10, first=True)") raises(AttributeError, "api.config.find('i1', value=10, first=True)")
raises(AttributeError, "api.config.find('not', byvalue=10, first=True)") raises(AttributeError, "api.config.find('not', value=10, first=True)")
raises(AttributeError, "api.config.find('i6', first=True)") raises(AttributeError, "api.config.find('i6', first=True)")
raises(ValueError, "api.value.set('od1.i6', 7, only_config=True, force_default=True)") raises(ValueError, "api.value.set('od1.i6', 7, only_config=True, force_default=True)")
raises(ValueError, "api.value.set('od1.i6', 7, only_config=True, force_default_if_same=True)") raises(ValueError, "api.value.set('od1.i6', 7, only_config=True, force_default_if_same=True)")

View file

@ -384,8 +384,8 @@ def test_access_by_get():
descr = make_description() descr = make_description()
api = getapi(Config(descr)) api = getapi(Config(descr))
raises(AttributeError, "api.option.find('idontexist')") raises(AttributeError, "api.option.find('idontexist')")
assert api.option.find('wantref', type='value', first=True) is False assert api.option.find('wantref', first=True).value.get() is False
assert api.option.find('dummy', type='value', first=True) is False assert api.option.find('dummy', first=True).value.get() is False
def test_access_by_get_whith_hide(): def test_access_by_get_whith_hide():
@ -398,7 +398,7 @@ def test_access_by_get_whith_hide():
BoolOption("d1", "")]) BoolOption("d1", "")])
api = getapi(Config(descr)) api = getapi(Config(descr))
api.property.read_write() api.property.read_write()
raises(AttributeError, "api.option.find('b1', type='value')") raises(AttributeError, "api.option.find('b1').value.get()")
def test_append_properties(): def test_append_properties():

View file

@ -35,6 +35,24 @@ def test_symlink_option():
assert api.option('c').value.get() is False assert api.option('c').value.get() is False
def test_symlink_assign_option():
boolopt = BoolOption("b", "", default=False)
linkopt = SymLinkOption("c", boolopt)
descr = OptionDescription("opt", "",
[linkopt, OptionDescription("s1", "", [boolopt])])
api = getapi(Config(descr))
raises(ConfigError, "api.option('c').value.set(True)")
def test_symlink_del_option():
boolopt = BoolOption("b", "", default=False)
linkopt = SymLinkOption("c", boolopt)
descr = OptionDescription("opt", "",
[linkopt, OptionDescription("s1", "", [boolopt])])
api = getapi(Config(descr))
raises(TypeError, "api.option('c').value.reset()")
def test_symlink_getproperties(): def test_symlink_getproperties():
boolopt = BoolOption('b', '', default=True, properties=('test',)) boolopt = BoolOption('b', '', default=True, properties=('test',))
linkopt = SymLinkOption("c", boolopt) linkopt = SymLinkOption("c", boolopt)

View file

@ -628,6 +628,8 @@ class TiramisuOption(CommonTiramisu):
self.config_bag) self.config_bag)
elif subfunc == 'make_dict' and self._get_option().impl_is_optiondescription(): elif subfunc == 'make_dict' and self._get_option().impl_is_optiondescription():
return self._make_dict return self._make_dict
elif subfunc == 'find' and self._get_option().impl_is_optiondescription():
return self._find
elif subfunc == 'list' and self._get_option().impl_is_optiondescription(): elif subfunc == 'list' and self._get_option().impl_is_optiondescription():
return self._list return self._list
elif subfunc == 'group_type' and self._get_option().impl_is_optiondescription(): elif subfunc == 'group_type' and self._get_option().impl_is_optiondescription():
@ -650,6 +652,32 @@ class TiramisuOption(CommonTiramisu):
withoption=withoption, withoption=withoption,
withvalue=withvalue) withvalue=withvalue)
def _find(self,
name,
value=undefined,
first=False):
"""find an option by name (only for optiondescription)"""
if not first:
ret = []
for path in self.config_bag.config.find(byname=name,
byvalue=value,
bytype=None,
type_='path',
_subpath=self.path,
config_bag=self.config_bag):
config_bag = self.config_bag.copy('nooption')
subconfig, name = config_bag.config.cfgimpl_get_home_by_path(path,
config_bag)
t_option = TiramisuOption(name,
path,
None, # index for a slave ?
subconfig,
config_bag)
if first:
return t_option
ret.append(t_option)
return ret
@count @count
def _group_type(self): def _group_type(self):
"""get type for an optiondescription (only for optiondescription)""" """get type for an optiondescription (only for optiondescription)"""
@ -864,17 +892,29 @@ class TiramisuContextOption(TiramisuContext):
@count @count
def find(self, def find(self,
name, name,
type='option', value=undefined,
first=False): first=False):
"""find an option by name""" """find an option by name"""
if first: if not first:
return self.config_bag.config.find_first(byname=name, ret = []
type_=type, for path in self.config_bag.config.find(byname=name,
config_bag=self.config_bag) byvalue=value,
else: bytype=None,
return self.config_bag.config.find(byname=name, type_='path',
type_=type, #_subpath=self.path,
config_bag=self.config_bag) config_bag=self.config_bag):
config_bag = self.config_bag.copy('nooption')
subconfig, name = config_bag.config.cfgimpl_get_home_by_path(path,
config_bag)
t_option = TiramisuOption(name,
path,
None, # index for a slave ?
subconfig,
config_bag)
if first:
return t_option
ret.append(t_option)
return ret
#@count #@count
#def get(self, path): #def get(self, path):
@ -928,12 +968,12 @@ class TiramisuContextConfig(TiramisuContext):
"""configuration methods""" """configuration methods"""
def find(self, def find(self,
name, name,
byvalue=undefined, value=undefined,
first=False): first=False):
"""find a path from option name and optionnaly a value to MetaConfig or GroupConfig""" """find a path from option name and optionnaly a value to MetaConfig or GroupConfig"""
if first: if first:
return self.config_bag.config.find_firsts(byname=name, return self.config_bag.config.find_firsts(byname=name,
byvalue=byvalue, byvalue=value,
config_bag=self.config_bag) config_bag=self.config_bag)
else: else:
raise APIError('not implemented yet') raise APIError('not implemented yet')

View file

@ -381,62 +381,15 @@ class SubConfig(object):
return value return value
def find(self, def find(self,
bytype,
byname,
byvalue,
config_bag, config_bag,
bytype=None, type_='option',
byname=None, _subpath=None,
byvalue=undefined, raise_if_not_found=True,
type_='option'): only_path=undefined,
""" only_option=undefined):
finds a list of options recursively in the config
:param bytype: Option class (BoolOption, StrOption, ...)
:param byname: filter by Option.impl_getname()
:param byvalue: filter by the option's value
:returns: list of matching Option objects
"""
return self.cfgimpl_get_context()._find(bytype,
byname,
byvalue,
config_bag,
first=False,
type_=type_,
_subpath=self.cfgimpl_get_path(False))
def find_first(self,
config_bag,
bytype=None,
byname=None,
byvalue=undefined,
type_='option',
raise_if_not_found=True):
"""
finds an option recursively in the config
:param bytype: Option class (BoolOption, StrOption, ...)
:param byname: filter by Option.impl_getname()
:param byvalue: filter by the option's value
:returns: list of matching Option objects
"""
return self.cfgimpl_get_context()._find(bytype,
byname,
byvalue,
config_bag,
first=True,
type_=type_,
_subpath=self.cfgimpl_get_path(False),
raise_if_not_found=raise_if_not_found)
def _find(self,
bytype,
byname,
byvalue,
config_bag,
first,
type_='option',
_subpath=None,
raise_if_not_found=True,
only_path=undefined,
only_option=undefined):
""" """
convenience method for finding an option that lives only in the subtree convenience method for finding an option that lives only in the subtree
@ -459,20 +412,14 @@ class SubConfig(object):
if type_ not in ('option', 'path', 'value'): # pragma: optional cover if type_ not in ('option', 'path', 'value'): # pragma: optional cover
raise ValueError(_('unknown type_ type {0}' raise ValueError(_('unknown type_ type {0}'
'for _find').format(type_)) 'for find').format(type_))
find_results = [] found = False
# if value and/or validate_properties are set, need all avalaible option
# If first one has no good value or not good property check second one
# and so on
only_first = first is True and byvalue is undefined and \
config_bag.validate_properties is False
if only_path is not undefined: if only_path is not undefined:
options = [(only_path, only_option)] options = [(only_path, only_option)]
else: else:
options = self.cfgimpl_get_description().impl_get_options_paths(bytype, options = self.cfgimpl_get_description().impl_get_options_paths(bytype,
byname, byname,
_subpath, _subpath,
only_first,
config_bag) config_bag)
for path, option in options: for path, option in options:
sconfig_bag = config_bag.copy('nooption') sconfig_bag = config_bag.copy('nooption')
@ -480,39 +427,34 @@ class SubConfig(object):
if not _filter_by_value(sconfig_bag): if not _filter_by_value(sconfig_bag):
continue continue
#remove option with propertyerror, ... #remove option with propertyerror, ...
if config_bag.validate_properties: if sconfig_bag.validate_properties:
try: try:
self.unwrap_from_path(path, self.unwrap_from_path(path,
config_bag) sconfig_bag)
self.cfgimpl_get_settings().validate_properties(path, self.cfgimpl_get_settings().validate_properties(path,
None, None,
config_bag) sconfig_bag)
except PropertiesOptionError: except PropertiesOptionError:
continue continue
if type_ == 'value': if type_ == 'value':
retval = self.getattr(path, retval = self.getattr(path,
None, None,
config_bag) sconfig_bag)
elif type_ == 'path': elif type_ == 'path':
retval = path retval = path
elif type_ == 'option': elif type_ == 'option':
retval = option retval = option
if first: found = True
return retval yield retval
else: return self._find_return_results(found,
find_results.append(retval)
return self._find_return_results(find_results,
raise_if_not_found) raise_if_not_found)
def _find_return_results(self, def _find_return_results(self,
find_results, found,
raise_if_not_found): raise_if_not_found):
if find_results == []: # pragma: optional cover if not found and raise_if_not_found:
if raise_if_not_found: raise AttributeError(_("no option found in config"
raise AttributeError(_("no option found in config" " with these criteria"))
" with these criteria"))
else:
return find_results
def make_dict(self, def make_dict(self,
config_bag, config_bag,
@ -565,13 +507,12 @@ class SubConfig(object):
"option")) "option"))
context = self.cfgimpl_get_context() context = self.cfgimpl_get_context()
if withoption is not None: if withoption is not None:
for path in context._find(bytype=None, for path in context.find(bytype=None,
byname=withoption, byname=withoption,
byvalue=withvalue, byvalue=withvalue,
first=False, type_='path',
type_='path', _subpath=self.cfgimpl_get_path(False),
_subpath=self.cfgimpl_get_path(False), config_bag=config_bag):
config_bag=config_bag):
path = '.'.join(path.split('.')[:-1]) path = '.'.join(path.split('.')[:-1])
opt = context.unwrap_from_path(path, opt = context.unwrap_from_path(path,
config_bag) config_bag)
@ -946,23 +887,21 @@ class GroupConfig(_CommonConfig):
_sub=False): _sub=False):
"""Find first not in current GroupConfig, but in each children """Find first not in current GroupConfig, but in each children
""" """
ret = []
#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, isinstance(self,
MetaConfig): MetaConfig):
bypath = self._find(bytype=None, bypath = next(self.find(bytype=None,
byvalue=undefined, byvalue=undefined,
byname=byname, byname=byname,
first=True, config_bag=config_bag,
config_bag=config_bag, type_='path',
type_='path', 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().impl_get_opt_by_path(bypath) byoption = self.cfgimpl_get_description().impl_get_opt_by_path(bypath)
ret = []
for child in self._impl_children: for child in self._impl_children:
nconfig_bag = config_bag.copy('nooption') nconfig_bag = config_bag.copy('nooption')
nconfig_bag.option = child nconfig_bag.option = child
@ -974,21 +913,25 @@ class GroupConfig(_CommonConfig):
config_bag=config_bag, config_bag=config_bag,
raise_if_not_found=False, raise_if_not_found=False,
_sub=True)) _sub=True))
elif child._find(None, else:
byname, try:
byvalue, next(child.find(None,
first=True, byname,
type_='path', byvalue,
config_bag=config_bag, type_='path',
raise_if_not_found=False, config_bag=config_bag,
only_path=bypath, raise_if_not_found=False,
only_option=byoption): only_path=bypath,
ret.append(child) only_option=byoption))
ret.append(child)
except StopIteration:
pass
if _sub: if _sub:
return ret return ret
else: else:
return GroupConfig(self._find_return_results(ret, self._find_return_results(ret != [],
raise_if_not_found)) raise_if_not_found)
return GroupConfig(ret)
def impl_getname(self): def impl_getname(self):
return self._impl_name return self._impl_name

View file

@ -81,9 +81,8 @@ class DynOptionDescription(OptionDescription):
None, None,
config_bag) config_bag)
if not isinstance(values, list): if not isinstance(values, list):
raise ValueError(_('invalid suffix "{}" for option "{}", must be a list' raise ValueError(_('DynOptionDescription callback for option "{}", is not a list ({})'
'').format(values, '').format(self.impl_get_display_name(), values))
self.impl_get_display_name()))
if len(values) > len(set(values)): if len(values) > len(set(values)):
raise ValueError(_('DynOptionDescription callback return not unique value')) raise ValueError(_('DynOptionDescription callback return not unique value'))
for val in values: for val in values:

View file

@ -19,6 +19,7 @@
# the whole pypy projet is under MIT licence # the whole pypy projet is under MIT licence
# ____________________________________________________________ # ____________________________________________________________
from copy import copy from copy import copy
from itertools import chain
from ..i18n import _ from ..i18n import _
@ -254,74 +255,61 @@ class OptionDescriptionWalk(CacheOptionDescription):
bytype, bytype,
byname, byname,
_subpath, _subpath,
only_first,
config_bag): config_bag):
find_results = [] def _filter_by_type(path,
option):
if isinstance(option,
bytype):
if byname is None:
if option.issubdyn():
for doption in self.build_dynoptions(option, config_bag):
dpath = doption.impl_getname(config_bag.config)
yield (dpath, doption)
else:
yield (path, option)
def _filter_by_name(path, def _filter_by_name(path,
option): option):
name = option.impl_getname() name = option.impl_getname()
if option.issubdyn(): if option.issubdyn():
found = False
if byname.startswith(name): if byname.startswith(name):
for doption in self.build_dynoptions(option, config_bag): for doption in self.build_dynoptions(option, config_bag):
if byname == doption.impl_getname(): if byname == doption.impl_getname():
dpath = doption.impl_getpath(config_bag.config) dpath = doption.impl_getpath(config_bag.config)
find_results.append((dpath, doption)) yield (dpath, doption)
found = True
break break
if not found:
return False
else: else:
if not byname == name: if byname == name:
return False yield (path, option)
find_results.append((path, option))
return True
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:
if option.issubdyn():
for doption in self.build_dynoptions(option, config_bag):
dpath = doption.impl_getname(config_bag.config)
find_results.append((dpath, doption))
else:
find_results.append((path, option))
return True
return False
def _filter(path, option): def _filter(path, option):
generators = []
if bytype is not None: if bytype is not None:
retval = _filter_by_type(path, option) generators.append(_filter_by_type(path, option))
if byname is None:
return retval
if byname is not None: if byname is not None:
return _filter_by_name(path, option) generators.append(_filter_by_name(path, option))
if len(generators) == 1:
return generators[0]
else:
return chain(*generators)
opts, paths = self._cache_paths opts, paths = self._cache_paths
for index, path in enumerate(paths): for index, option in enumerate(opts):
option = opts[index]
if option.impl_is_optiondescription(): if option.impl_is_optiondescription():
continue continue
path = paths[index]
if _subpath is not None and not path.startswith(_subpath + '.'): if _subpath is not None and not path.startswith(_subpath + '.'):
continue continue
if bytype == byname is None: if bytype == byname is None:
if option.issubdyn(): if option.issubdyn():
for doption in self.build_dynoptions(option, config_bag): for doption in self.build_dynoptions(option, config_bag):
dpath = doption.impl_getpath(config_bag.config) dpath = doption.impl_getpath(config_bag.config)
find_results.append((dpath, doption)) yield (dpath, doption)
else: else:
find_results.append((dpath, option)) yield (dpath, option)
else: else:
if _filter(path, option) is False: for ret in _filter(path, option):
continue yield ret
if only_first:
return find_results
return find_results
def impl_getchild(self, def impl_getchild(self,
name, name,

View file

@ -34,23 +34,23 @@ class Properties(Cache):
# properties # properties
def setproperties(self, path, properties): def setproperties(self, path, properties):
if DEBUG: if DEBUG: # pragma: no cover
print('setproperties', path, properties) print('setproperties', path, properties)
self._properties[path] = properties self._properties[path] = properties
def getproperties(self, path, default_properties): def getproperties(self, path, default_properties):
ret = self._properties.get(path, frozenset(default_properties)) ret = self._properties.get(path, frozenset(default_properties))
if DEBUG: if DEBUG: # pragma: no cover
print('getproperties', path, ret) print('getproperties', path, ret)
return ret return ret
def reset_all_properties(self): def reset_all_properties(self):
if DEBUG: if DEBUG: # pragma: no cover
print('reset_all_properties') print('reset_all_properties')
self._properties.clear() self._properties.clear()
def delproperties(self, path): def delproperties(self, path):
if DEBUG: if DEBUG: # pragma: no cover
print('delproperties', path) print('delproperties', path)
if path in self._properties: if path in self._properties:
del(self._properties[path]) del(self._properties[path])
@ -74,7 +74,7 @@ class Permissives(Cache):
super(Permissives, self).__init__(storage) super(Permissives, self).__init__(storage)
def setpermissive(self, path, permissive): def setpermissive(self, path, permissive):
if DEBUG: if DEBUG: # pragma: no cover
print('setpermissive', path, permissive) print('setpermissive', path, permissive)
if not permissive: if not permissive:
if path in self._permissives: if path in self._permissives:
@ -84,7 +84,7 @@ class Permissives(Cache):
def getpermissive(self, path=None): def getpermissive(self, path=None):
ret = self._permissives.get(path, frozenset()) ret = self._permissives.get(path, frozenset())
if DEBUG: if DEBUG: # pragma: no cover
print('getpermissive', path, ret) print('getpermissive', path, ret)
return ret return ret

View file

@ -75,7 +75,7 @@ class Values(Cache):
"""set value for a path """set value for a path
a specified value must be associated to an owner a specified value must be associated to an owner
""" """
if DEBUG: if DEBUG: # pragma: no cover
print('setvalue', path, value, owner, index, id(self)) print('setvalue', path, value, owner, index, id(self))
values = [] values = []
vidx = None vidx = None
@ -97,9 +97,7 @@ class Values(Cache):
return: boolean return: boolean
""" """
has_path = path in self._values[0] has_path = path in self._values[0]
if path.startswith('subod.subodval'): if DEBUG: # pragma: no cover
raise Exception('arf ...')
if DEBUG:
print('hasvalue', path, index, has_path, id(self)) print('hasvalue', path, index, has_path, id(self))
if index is None: if index is None:
return has_path return has_path
@ -113,7 +111,7 @@ class Values(Cache):
""" """
_values == ((path1, path2), ((idx1_1, idx1_2), None), ((value1_1, value1_2), value2), ((owner1_1, owner1_2), owner2)) _values == ((path1, path2), ((idx1_1, idx1_2), None), ((value1_1, value1_2), value2), ((owner1_1, owner1_2), owner2))
""" """
if DEBUG: if DEBUG: # pragma: no cover
print('reduce_index', path, index, id(self)) print('reduce_index', path, index, id(self))
path_idx = self._values[0].index(path) path_idx = self._values[0].index(path)
indexes = self._values[1][path_idx] indexes = self._values[1][path_idx]
@ -128,7 +126,7 @@ class Values(Cache):
self._values = tuple(values) self._values = tuple(values)
def resetvalue_index(self, path, index): def resetvalue_index(self, path, index):
if DEBUG: if DEBUG: # pragma: no cover
print('resetvalue_index', path, index, id(self)) print('resetvalue_index', path, index, id(self))
def _resetvalue(nb): def _resetvalue(nb):
values_idx = list(values[nb]) values_idx = list(values[nb])
@ -161,7 +159,7 @@ class Values(Cache):
def resetvalue(self, path, commit): def resetvalue(self, path, commit):
"""remove value means delete value in storage """remove value means delete value in storage
""" """
if DEBUG: if DEBUG: # pragma: no cover
print('resetvalue', path, id(self)) print('resetvalue', path, id(self))
def _resetvalue(nb): def _resetvalue(nb):
lst = list(self._values[nb]) lst = list(self._values[nb])
@ -211,7 +209,7 @@ class Values(Cache):
with_value) with_value)
if owner is undefined: if owner is undefined:
owner = default owner = default
if DEBUG: if DEBUG: # pragma: no cover
print('getvalue', path, index, value, owner, id(self)) print('getvalue', path, index, value, owner, id(self))
if with_value: if with_value:
return owner, value return owner, value