key is now always path and change opt by path dictionary storage
This commit is contained in:
parent
707a215a2c
commit
b6bb685ca5
|
@ -20,13 +20,13 @@ def test_cache():
|
||||||
values = c.cfgimpl_get_values()
|
values = c.cfgimpl_get_values()
|
||||||
settings = c.cfgimpl_get_settings()
|
settings = c.cfgimpl_get_settings()
|
||||||
c.u1
|
c.u1
|
||||||
assert od1.u1 in values._p_.get_cached('value', c)
|
assert 'u1' in values._p_.get_cached('value', c)
|
||||||
assert od1.u1 in settings._p_.get_cached('property', c)
|
assert 'u1' in settings._p_.get_cached('property', c)
|
||||||
c.u2
|
c.u2
|
||||||
assert od1.u1 in values._p_.get_cached('value', c)
|
assert 'u1' in values._p_.get_cached('value', c)
|
||||||
assert od1.u1 in settings._p_.get_cached('property', c)
|
assert 'u1' in settings._p_.get_cached('property', c)
|
||||||
assert od1.u2 in values._p_.get_cached('value', c)
|
assert 'u2' in values._p_.get_cached('value', c)
|
||||||
assert od1.u2 in settings._p_.get_cached('property', c)
|
assert 'u2' in settings._p_.get_cached('property', c)
|
||||||
|
|
||||||
|
|
||||||
def test_cache_reset():
|
def test_cache_reset():
|
||||||
|
@ -36,44 +36,44 @@ def test_cache_reset():
|
||||||
settings = c.cfgimpl_get_settings()
|
settings = c.cfgimpl_get_settings()
|
||||||
#when change a value
|
#when change a value
|
||||||
c.u1
|
c.u1
|
||||||
assert od1.u1 in values._p_.get_cached('value', c)
|
assert 'u1' in values._p_.get_cached('value', c)
|
||||||
assert od1.u1 in settings._p_.get_cached('property', c)
|
assert 'u1' in settings._p_.get_cached('property', c)
|
||||||
c.u2 = 1
|
c.u2 = 1
|
||||||
assert od1.u1 not in values._p_.get_cached('value', c)
|
assert 'u1' not in values._p_.get_cached('value', c)
|
||||||
assert od1.u1 not in settings._p_.get_cached('property', c)
|
assert 'u1' not in settings._p_.get_cached('property', c)
|
||||||
#when remove a value
|
#when remove a value
|
||||||
c.u1
|
c.u1
|
||||||
assert od1.u1 in values._p_.get_cached('value', c)
|
assert 'u1' in values._p_.get_cached('value', c)
|
||||||
assert od1.u1 in settings._p_.get_cached('property', c)
|
assert 'u1' in settings._p_.get_cached('property', c)
|
||||||
del(c.u2)
|
del(c.u2)
|
||||||
assert od1.u1 not in values._p_.get_cached('value', c)
|
assert 'u1' not in values._p_.get_cached('value', c)
|
||||||
assert od1.u1 not in settings._p_.get_cached('property', c)
|
assert 'u1' not in settings._p_.get_cached('property', c)
|
||||||
#when add/del property
|
#when add/del property
|
||||||
c.u1
|
c.u1
|
||||||
assert od1.u1 in values._p_.get_cached('value', c)
|
assert 'u1' in values._p_.get_cached('value', c)
|
||||||
assert od1.u1 in settings._p_.get_cached('property', c)
|
assert 'u1' in settings._p_.get_cached('property', c)
|
||||||
c.cfgimpl_get_settings()[od1.u2].append('test')
|
c.cfgimpl_get_settings()[od1.u2].append('test')
|
||||||
assert od1.u1 not in values._p_.get_cached('value', c)
|
assert 'u1' not in values._p_.get_cached('value', c)
|
||||||
assert od1.u1 not in settings._p_.get_cached('property', c)
|
assert 'u1' not in settings._p_.get_cached('property', c)
|
||||||
c.u1
|
c.u1
|
||||||
assert od1.u1 in values._p_.get_cached('value', c)
|
assert 'u1' in values._p_.get_cached('value', c)
|
||||||
assert od1.u1 in settings._p_.get_cached('property', c)
|
assert 'u1' in settings._p_.get_cached('property', c)
|
||||||
c.cfgimpl_get_settings()[od1.u2].remove('test')
|
c.cfgimpl_get_settings()[od1.u2].remove('test')
|
||||||
assert od1.u1 not in values._p_.get_cached('value', c)
|
assert 'u1' not in values._p_.get_cached('value', c)
|
||||||
assert od1.u1 not in settings._p_.get_cached('property', c)
|
assert 'u1' not in settings._p_.get_cached('property', c)
|
||||||
#when enable/disabled property
|
#when enable/disabled property
|
||||||
c.u1
|
c.u1
|
||||||
assert od1.u1 in values._p_.get_cached('value', c)
|
assert 'u1' in values._p_.get_cached('value', c)
|
||||||
assert od1.u1 in settings._p_.get_cached('property', c)
|
assert 'u1' in settings._p_.get_cached('property', c)
|
||||||
c.cfgimpl_get_settings().append('test')
|
c.cfgimpl_get_settings().append('test')
|
||||||
assert od1.u1 not in values._p_.get_cached('value', c)
|
assert 'u1' not in values._p_.get_cached('value', c)
|
||||||
assert od1.u1 not in settings._p_.get_cached('property', c)
|
assert 'u1' not in settings._p_.get_cached('property', c)
|
||||||
c.u1
|
c.u1
|
||||||
assert od1.u1 in values._p_.get_cached('value', c)
|
assert 'u1' in values._p_.get_cached('value', c)
|
||||||
assert od1.u1 in settings._p_.get_cached('property', c)
|
assert 'u1' in settings._p_.get_cached('property', c)
|
||||||
c.cfgimpl_get_settings().remove('test')
|
c.cfgimpl_get_settings().remove('test')
|
||||||
assert od1.u1 not in values._p_.get_cached('value', c)
|
assert 'u1' not in values._p_.get_cached('value', c)
|
||||||
assert od1.u1 not in settings._p_.get_cached('property', c)
|
assert 'u1' not in settings._p_.get_cached('property', c)
|
||||||
|
|
||||||
|
|
||||||
def test_cache_reset_multi():
|
def test_cache_reset_multi():
|
||||||
|
@ -83,32 +83,32 @@ def test_cache_reset_multi():
|
||||||
settings = c.cfgimpl_get_settings()
|
settings = c.cfgimpl_get_settings()
|
||||||
#when change a value
|
#when change a value
|
||||||
c.u1
|
c.u1
|
||||||
assert od1.u1 in values._p_.get_cached('value', c)
|
assert 'u1' in values._p_.get_cached('value', c)
|
||||||
assert od1.u1 in settings._p_.get_cached('property', c)
|
assert 'u1' in settings._p_.get_cached('property', c)
|
||||||
c.u3 = [1]
|
c.u3 = [1]
|
||||||
assert od1.u1 not in values._p_.get_cached('value', c)
|
assert 'u1' not in values._p_.get_cached('value', c)
|
||||||
assert od1.u1 not in settings._p_.get_cached('property', c)
|
assert 'u1' not in settings._p_.get_cached('property', c)
|
||||||
#when append value
|
#when append value
|
||||||
c.u1
|
c.u1
|
||||||
assert od1.u1 in values._p_.get_cached('value', c)
|
assert 'u1' in values._p_.get_cached('value', c)
|
||||||
assert od1.u1 in settings._p_.get_cached('property', c)
|
assert 'u1' in settings._p_.get_cached('property', c)
|
||||||
c.u3.append(1)
|
c.u3.append(1)
|
||||||
assert od1.u1 not in values._p_.get_cached('value', c)
|
assert 'u1' not in values._p_.get_cached('value', c)
|
||||||
assert od1.u1 not in settings._p_.get_cached('property', c)
|
assert 'u1' not in settings._p_.get_cached('property', c)
|
||||||
#when pop value
|
#when pop value
|
||||||
c.u1
|
c.u1
|
||||||
assert od1.u1 in values._p_.get_cached('value', c)
|
assert 'u1' in values._p_.get_cached('value', c)
|
||||||
assert od1.u1 in settings._p_.get_cached('property', c)
|
assert 'u1' in settings._p_.get_cached('property', c)
|
||||||
c.u3.pop(1)
|
c.u3.pop(1)
|
||||||
assert od1.u1 not in values._p_.get_cached('value', c)
|
assert 'u1' not in values._p_.get_cached('value', c)
|
||||||
assert od1.u1 not in settings._p_.get_cached('property', c)
|
assert 'u1' not in settings._p_.get_cached('property', c)
|
||||||
#when remove a value
|
#when remove a value
|
||||||
c.u1
|
c.u1
|
||||||
assert od1.u1 in values._p_.get_cached('value', c)
|
assert 'u1' in values._p_.get_cached('value', c)
|
||||||
assert od1.u1 in settings._p_.get_cached('property', c)
|
assert 'u1' in settings._p_.get_cached('property', c)
|
||||||
del(c.u3)
|
del(c.u3)
|
||||||
assert od1.u1 not in values._p_.get_cached('value', c)
|
assert 'u1' not in values._p_.get_cached('value', c)
|
||||||
assert od1.u1 not in settings._p_.get_cached('property', c)
|
assert 'u1' not in settings._p_.get_cached('property', c)
|
||||||
|
|
||||||
|
|
||||||
def test_reset_cache():
|
def test_reset_cache():
|
||||||
|
@ -117,23 +117,23 @@ def test_reset_cache():
|
||||||
values = c.cfgimpl_get_values()
|
values = c.cfgimpl_get_values()
|
||||||
settings = c.cfgimpl_get_settings()
|
settings = c.cfgimpl_get_settings()
|
||||||
c.u1
|
c.u1
|
||||||
assert od1.u1 in values._p_.get_cached('value', c)
|
assert 'u1' in values._p_.get_cached('value', c)
|
||||||
assert od1.u1 in settings._p_.get_cached('property', c)
|
assert 'u1' in settings._p_.get_cached('property', c)
|
||||||
c.cfgimpl_reset_cache()
|
c.cfgimpl_reset_cache()
|
||||||
assert od1.u1 not in values._p_.get_cached('value', c)
|
assert 'u1' not in values._p_.get_cached('value', c)
|
||||||
assert od1.u1 not in settings._p_.get_cached('property', c)
|
assert 'u1' not in settings._p_.get_cached('property', c)
|
||||||
c.u1
|
c.u1
|
||||||
sleep(1)
|
sleep(1)
|
||||||
c.u2
|
c.u2
|
||||||
assert od1.u1 in values._p_.get_cached('value', c)
|
assert 'u1' in values._p_.get_cached('value', c)
|
||||||
assert od1.u1 in settings._p_.get_cached('property', c)
|
assert 'u1' in settings._p_.get_cached('property', c)
|
||||||
assert od1.u2 in values._p_.get_cached('value', c)
|
assert 'u2' in values._p_.get_cached('value', c)
|
||||||
assert od1.u2 in settings._p_.get_cached('property', c)
|
assert 'u2' in settings._p_.get_cached('property', c)
|
||||||
c.cfgimpl_reset_cache()
|
c.cfgimpl_reset_cache()
|
||||||
assert od1.u1 not in values._p_.get_cached('value', c)
|
assert 'u1' not in values._p_.get_cached('value', c)
|
||||||
assert od1.u1 not in settings._p_.get_cached('property', c)
|
assert 'u1' not in settings._p_.get_cached('property', c)
|
||||||
assert od1.u2 not in values._p_.get_cached('value', c)
|
assert 'u2' not in values._p_.get_cached('value', c)
|
||||||
assert od1.u2 not in settings._p_.get_cached('property', c)
|
assert 'u2' not in settings._p_.get_cached('property', c)
|
||||||
|
|
||||||
|
|
||||||
def test_reset_cache_only_expired():
|
def test_reset_cache_only_expired():
|
||||||
|
@ -142,22 +142,22 @@ def test_reset_cache_only_expired():
|
||||||
values = c.cfgimpl_get_values()
|
values = c.cfgimpl_get_values()
|
||||||
settings = c.cfgimpl_get_settings()
|
settings = c.cfgimpl_get_settings()
|
||||||
c.u1
|
c.u1
|
||||||
assert od1.u1 in values._p_.get_cached('value', c)
|
assert 'u1' in values._p_.get_cached('value', c)
|
||||||
assert od1.u1 in settings._p_.get_cached('property', c)
|
assert 'u1' in settings._p_.get_cached('property', c)
|
||||||
c.cfgimpl_reset_cache(True)
|
c.cfgimpl_reset_cache(True)
|
||||||
assert od1.u1 in values._p_.get_cached('value', c)
|
assert 'u1' in values._p_.get_cached('value', c)
|
||||||
assert od1.u1 in settings._p_.get_cached('property', c)
|
assert 'u1' in settings._p_.get_cached('property', c)
|
||||||
sleep(1)
|
sleep(1)
|
||||||
c.u2
|
c.u2
|
||||||
assert od1.u1 in values._p_.get_cached('value', c)
|
assert 'u1' in values._p_.get_cached('value', c)
|
||||||
assert od1.u1 in settings._p_.get_cached('property', c)
|
assert 'u1' in settings._p_.get_cached('property', c)
|
||||||
assert od1.u2 in values._p_.get_cached('value', c)
|
assert 'u2' in values._p_.get_cached('value', c)
|
||||||
assert od1.u2 in settings._p_.get_cached('property', c)
|
assert 'u2' in settings._p_.get_cached('property', c)
|
||||||
c.cfgimpl_reset_cache(True)
|
c.cfgimpl_reset_cache(True)
|
||||||
assert od1.u1 not in values._p_.get_cached('value', c)
|
assert 'u1' not in values._p_.get_cached('value', c)
|
||||||
assert od1.u1 not in settings._p_.get_cached('property', c)
|
assert 'u1' not in settings._p_.get_cached('property', c)
|
||||||
assert od1.u2 in values._p_.get_cached('value', c)
|
assert 'u2' in values._p_.get_cached('value', c)
|
||||||
assert od1.u2 in settings._p_.get_cached('property', c)
|
assert 'u2' in settings._p_.get_cached('property', c)
|
||||||
|
|
||||||
|
|
||||||
def test_reset_cache_only():
|
def test_reset_cache_only():
|
||||||
|
@ -166,14 +166,14 @@ def test_reset_cache_only():
|
||||||
values = c.cfgimpl_get_values()
|
values = c.cfgimpl_get_values()
|
||||||
settings = c.cfgimpl_get_settings()
|
settings = c.cfgimpl_get_settings()
|
||||||
c.u1
|
c.u1
|
||||||
assert od1.u1 in values._p_.get_cached('value', c)
|
assert 'u1' in values._p_.get_cached('value', c)
|
||||||
assert od1.u1 in settings._p_.get_cached('property', c)
|
assert 'u1' in settings._p_.get_cached('property', c)
|
||||||
c.cfgimpl_reset_cache(only=('values',))
|
c.cfgimpl_reset_cache(only=('values',))
|
||||||
assert od1.u1 not in values._p_.get_cached('value', c)
|
assert 'u1' not in values._p_.get_cached('value', c)
|
||||||
assert od1.u1 in settings._p_.get_cached('property', c)
|
assert 'u1' in settings._p_.get_cached('property', c)
|
||||||
c.u1
|
c.u1
|
||||||
assert od1.u1 in values._p_.get_cached('value', c)
|
assert 'u1' in values._p_.get_cached('value', c)
|
||||||
assert od1.u1 in settings._p_.get_cached('property', c)
|
assert 'u1' in settings._p_.get_cached('property', c)
|
||||||
c.cfgimpl_reset_cache(only=('settings',))
|
c.cfgimpl_reset_cache(only=('settings',))
|
||||||
assert od1.u1 in values._p_.get_cached('value', c)
|
assert 'u1' in values._p_.get_cached('value', c)
|
||||||
assert od1.u1 not in settings._p_.get_cached('property', c)
|
assert 'u1' not in settings._p_.get_cached('property', c)
|
||||||
|
|
|
@ -39,6 +39,22 @@ def test_base_config():
|
||||||
assert dm._name == 'dummy'
|
assert dm._name == 'dummy'
|
||||||
|
|
||||||
|
|
||||||
|
def test_base_path():
|
||||||
|
gcdummy = BoolOption('dummy', 'dummy', default=False)
|
||||||
|
descr = OptionDescription('tiramisu', '', [gcdummy])
|
||||||
|
cfg = Config(descr)
|
||||||
|
assert cfg._impl_path is None
|
||||||
|
base = OptionDescription('config', '', [descr])
|
||||||
|
cfg = Config(base)
|
||||||
|
assert cfg._impl_path is None
|
||||||
|
assert cfg.tiramisu._impl_path == 'tiramisu'
|
||||||
|
nbase = OptionDescription('baseconfig', '', [base])
|
||||||
|
cfg = Config(nbase)
|
||||||
|
assert cfg._impl_path is None
|
||||||
|
assert cfg.config._impl_path == 'config'
|
||||||
|
assert cfg.config.tiramisu._impl_path == 'config.tiramisu'
|
||||||
|
|
||||||
|
|
||||||
def test_reset_value():
|
def test_reset_value():
|
||||||
descr = make_description()
|
descr = make_description()
|
||||||
cfg = Config(descr)
|
cfg = Config(descr)
|
||||||
|
|
|
@ -164,3 +164,9 @@ def test_not_meta():
|
||||||
meta.set_contexts('od1.i1', 7)
|
meta.set_contexts('od1.i1', 7)
|
||||||
assert conf1.od1.i1 == conf2.od1.i1 == 7
|
assert conf1.od1.i1 == conf2.od1.i1 == 7
|
||||||
assert conf1.getowner('od1.i1') is conf2.getowner('od1.i1') is owners.user
|
assert conf1.getowner('od1.i1') is conf2.getowner('od1.i1') is owners.user
|
||||||
|
|
||||||
|
|
||||||
|
def test_meta_path():
|
||||||
|
meta = make_description()
|
||||||
|
assert meta._impl_path is None
|
||||||
|
assert meta.od1._impl_path == 'od1'
|
||||||
|
|
|
@ -494,7 +494,7 @@ def test_callback_hidden():
|
||||||
od2 = OptionDescription('od2', '', [opt2])
|
od2 = OptionDescription('od2', '', [opt2])
|
||||||
maconfig = OptionDescription('rootconfig', '', [od1, od2])
|
maconfig = OptionDescription('rootconfig', '', [od1, od2])
|
||||||
cfg = Config(maconfig)
|
cfg = Config(maconfig)
|
||||||
cfg.cfgimpl_get_settings().set_permissive(('hidden',))
|
cfg.cfgimpl_get_settings().setpermissive(('hidden',))
|
||||||
cfg.read_write()
|
cfg.read_write()
|
||||||
raises(PropertiesOptionError, 'cfg.od1.opt1')
|
raises(PropertiesOptionError, 'cfg.od1.opt1')
|
||||||
cfg.od2.opt2
|
cfg.od2.opt2
|
||||||
|
|
|
@ -333,15 +333,15 @@ def test_reset_properties():
|
||||||
setting.reset()
|
setting.reset()
|
||||||
assert setting._p_.get_properties(cfg) == {}
|
assert setting._p_.get_properties(cfg) == {}
|
||||||
setting[option].append('test')
|
setting[option].append('test')
|
||||||
assert setting._p_.get_properties(cfg) == {option: set(('test',))}
|
assert setting._p_.get_properties(cfg) == {'gc.dummy': set(('test',))}
|
||||||
setting.reset()
|
setting.reset()
|
||||||
assert setting._p_.get_properties(cfg) == {option: set(('test',))}
|
assert setting._p_.get_properties(cfg) == {'gc.dummy': set(('test',))}
|
||||||
setting.append('frozen')
|
setting.append('frozen')
|
||||||
assert setting._p_.get_properties(cfg) == {None: set(('frozen', 'expire', 'validator')), option: set(('test',))}
|
assert setting._p_.get_properties(cfg) == {None: set(('frozen', 'expire', 'validator')), 'gc.dummy': set(('test',))}
|
||||||
setting.reset(option)
|
setting.reset(option)
|
||||||
assert setting._p_.get_properties(cfg) == {None: set(('frozen', 'expire', 'validator'))}
|
assert setting._p_.get_properties(cfg) == {None: set(('frozen', 'expire', 'validator'))}
|
||||||
setting[option].append('test')
|
setting[option].append('test')
|
||||||
assert setting._p_.get_properties(cfg) == {None: set(('frozen', 'expire', 'validator')), option: set(('test',))}
|
assert setting._p_.get_properties(cfg) == {None: set(('frozen', 'expire', 'validator')), 'gc.dummy': set(('test',))}
|
||||||
setting.reset(all_properties=True)
|
setting.reset(all_properties=True)
|
||||||
assert setting._p_.get_properties(cfg) == {}
|
assert setting._p_.get_properties(cfg) == {}
|
||||||
raises(ValueError, 'setting.reset(all_properties=True, opt=option)')
|
raises(ValueError, 'setting.reset(all_properties=True, opt=option)')
|
||||||
|
|
|
@ -21,7 +21,7 @@ def test_permissive():
|
||||||
except PropertiesOptionError, err:
|
except PropertiesOptionError, err:
|
||||||
props = err.proptype
|
props = err.proptype
|
||||||
assert props == ['disabled']
|
assert props == ['disabled']
|
||||||
setting.set_permissive(('disabled',))
|
setting.setpermissive(('disabled',))
|
||||||
props = []
|
props = []
|
||||||
try:
|
try:
|
||||||
config.u1
|
config.u1
|
||||||
|
@ -50,7 +50,7 @@ def test_permissive_mandatory():
|
||||||
except PropertiesOptionError, err:
|
except PropertiesOptionError, err:
|
||||||
props = err.proptype
|
props = err.proptype
|
||||||
assert props == ['disabled', 'mandatory']
|
assert props == ['disabled', 'mandatory']
|
||||||
setting.set_permissive(('mandatory', 'disabled',))
|
setting.setpermissive(('mandatory', 'disabled',))
|
||||||
setting.append('permissive')
|
setting.append('permissive')
|
||||||
config.u1
|
config.u1
|
||||||
setting.remove('permissive')
|
setting.remove('permissive')
|
||||||
|
@ -66,7 +66,7 @@ def test_permissive_frozen():
|
||||||
config = Config(descr)
|
config = Config(descr)
|
||||||
setting = config.cfgimpl_get_settings()
|
setting = config.cfgimpl_get_settings()
|
||||||
config.read_write()
|
config.read_write()
|
||||||
setting.set_permissive(('frozen', 'disabled',))
|
setting.setpermissive(('frozen', 'disabled',))
|
||||||
try:
|
try:
|
||||||
config.u1 = 1
|
config.u1 = 1
|
||||||
except PropertiesOptionError, err:
|
except PropertiesOptionError, err:
|
||||||
|
|
|
@ -35,15 +35,16 @@ def gen_id(config):
|
||||||
|
|
||||||
class SubConfig(BaseInformation):
|
class SubConfig(BaseInformation):
|
||||||
"sub configuration management entry"
|
"sub configuration management entry"
|
||||||
__slots__ = ('_impl_context', '_impl_descr')
|
__slots__ = ('_impl_context', '_impl_descr', '_impl_path')
|
||||||
|
|
||||||
def __init__(self, descr, context):
|
def __init__(self, descr, context, subpath=None):
|
||||||
""" Configuration option management master class
|
""" Configuration option management master class
|
||||||
|
|
||||||
:param descr: describes the configuration schema
|
:param descr: describes the configuration schema
|
||||||
:type descr: an instance of ``option.OptionDescription``
|
:type descr: an instance of ``option.OptionDescription``
|
||||||
:param context: the current root config
|
:param context: the current root config
|
||||||
:type context: `Config`
|
:type context: `Config`
|
||||||
|
:type subpath: `str` with the path name
|
||||||
"""
|
"""
|
||||||
# main option description
|
# main option description
|
||||||
if not isinstance(descr, OptionDescription):
|
if not isinstance(descr, OptionDescription):
|
||||||
|
@ -54,6 +55,7 @@ class SubConfig(BaseInformation):
|
||||||
if not isinstance(context, SubConfig):
|
if not isinstance(context, SubConfig):
|
||||||
raise ValueError('context must be a SubConfig')
|
raise ValueError('context must be a SubConfig')
|
||||||
self._impl_context = context
|
self._impl_context = context
|
||||||
|
self._impl_path = subpath
|
||||||
|
|
||||||
def cfgimpl_reset_cache(self, only_expired=False, only=('values',
|
def cfgimpl_reset_cache(self, only_expired=False, only=('values',
|
||||||
'settings')):
|
'settings')):
|
||||||
|
@ -183,7 +185,11 @@ class SubConfig(BaseInformation):
|
||||||
return homeconfig.__setattr__(name, value)
|
return homeconfig.__setattr__(name, value)
|
||||||
child = getattr(self.cfgimpl_get_description(), name)
|
child = getattr(self.cfgimpl_get_description(), name)
|
||||||
if not isinstance(child, SymLinkOption):
|
if not isinstance(child, SymLinkOption):
|
||||||
self.cfgimpl_get_values().setitem(child, value,
|
if self._impl_path is None:
|
||||||
|
path = name
|
||||||
|
else:
|
||||||
|
path = self._impl_path + '.' + name
|
||||||
|
self.cfgimpl_get_values().setitem(child, value, path,
|
||||||
force_permissive=force_permissive)
|
force_permissive=force_permissive)
|
||||||
else:
|
else:
|
||||||
context = self.cfgimpl_get_context()
|
context = self.cfgimpl_get_context()
|
||||||
|
@ -193,7 +199,7 @@ class SubConfig(BaseInformation):
|
||||||
|
|
||||||
def __delattr__(self, name):
|
def __delattr__(self, name):
|
||||||
child = getattr(self.cfgimpl_get_description(), name)
|
child = getattr(self.cfgimpl_get_description(), name)
|
||||||
del(self.cfgimpl_get_values()[child])
|
self.cfgimpl_get_values().__delitem__(child)
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
return self._getattr(name)
|
return self._getattr(name)
|
||||||
|
@ -222,6 +228,10 @@ class SubConfig(BaseInformation):
|
||||||
return object.__getattribute__(self, name)
|
return object.__getattribute__(self, name)
|
||||||
opt_or_descr = getattr(self.cfgimpl_get_description(), name)
|
opt_or_descr = getattr(self.cfgimpl_get_description(), name)
|
||||||
# symlink options
|
# symlink options
|
||||||
|
if self._impl_path is None:
|
||||||
|
subpath = name
|
||||||
|
else:
|
||||||
|
subpath = self._impl_path + '.' + name
|
||||||
if isinstance(opt_or_descr, SymLinkOption):
|
if isinstance(opt_or_descr, SymLinkOption):
|
||||||
context = self.cfgimpl_get_context()
|
context = self.cfgimpl_get_context()
|
||||||
path = context.cfgimpl_get_description().impl_get_path_by_opt(
|
path = context.cfgimpl_get_description().impl_get_path_by_opt(
|
||||||
|
@ -231,12 +241,13 @@ class SubConfig(BaseInformation):
|
||||||
force_permissive=force_permissive)
|
force_permissive=force_permissive)
|
||||||
elif isinstance(opt_or_descr, OptionDescription):
|
elif isinstance(opt_or_descr, OptionDescription):
|
||||||
self.cfgimpl_get_settings().validate_properties(
|
self.cfgimpl_get_settings().validate_properties(
|
||||||
opt_or_descr, True, False, force_permissive=force_permissive,
|
opt_or_descr, True, False, path=subpath,
|
||||||
|
force_permissive=force_permissive,
|
||||||
force_properties=force_properties)
|
force_properties=force_properties)
|
||||||
return SubConfig(opt_or_descr, self.cfgimpl_get_context())
|
return SubConfig(opt_or_descr, self.cfgimpl_get_context(), subpath)
|
||||||
else:
|
else:
|
||||||
return self.cfgimpl_get_values().getitem(
|
return self.cfgimpl_get_values().getitem(
|
||||||
opt_or_descr,
|
opt_or_descr, path=subpath,
|
||||||
validate=validate,
|
validate=validate,
|
||||||
force_properties=force_properties,
|
force_properties=force_properties,
|
||||||
force_permissive=force_permissive)
|
force_permissive=force_permissive)
|
||||||
|
@ -555,6 +566,7 @@ class MetaConfig(CommonConfig):
|
||||||
if not isinstance(children, list):
|
if not isinstance(children, list):
|
||||||
raise ValueError(_("metaconfig's children must be a list"))
|
raise ValueError(_("metaconfig's children must be a list"))
|
||||||
self._impl_descr = None
|
self._impl_descr = None
|
||||||
|
self._impl_path = None
|
||||||
if meta:
|
if meta:
|
||||||
for child in children:
|
for child in children:
|
||||||
if not isinstance(child, CommonConfig):
|
if not isinstance(child, CommonConfig):
|
||||||
|
|
|
@ -152,24 +152,25 @@ populate_multitypes()
|
||||||
|
|
||||||
class Property(object):
|
class Property(object):
|
||||||
"a property is responsible of the option's value access rules"
|
"a property is responsible of the option's value access rules"
|
||||||
__slots__ = ('_setting', '_properties', '_opt')
|
__slots__ = ('_setting', '_properties', '_opt', '_path')
|
||||||
|
|
||||||
def __init__(self, setting, prop, opt=None):
|
def __init__(self, setting, prop, opt=None, path=None):
|
||||||
self._opt = opt
|
self._opt = opt
|
||||||
|
self._path = path
|
||||||
self._setting = setting
|
self._setting = setting
|
||||||
self._properties = prop
|
self._properties = prop
|
||||||
|
|
||||||
def append(self, propname):
|
def append(self, propname):
|
||||||
self._properties.add(propname)
|
self._properties.add(propname)
|
||||||
self._setting._setproperties(self._properties, self._opt)
|
self._setting._setproperties(self._properties, self._opt, self._path)
|
||||||
|
|
||||||
def remove(self, propname):
|
def remove(self, propname):
|
||||||
if propname in self._properties:
|
if propname in self._properties:
|
||||||
self._properties.remove(propname)
|
self._properties.remove(propname)
|
||||||
self._setting._setproperties(self._properties, self._opt)
|
self._setting._setproperties(self._properties, self._opt, self._path)
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
self._setting.reset(opt=self._opt)
|
self._setting.reset(path=self._path)
|
||||||
|
|
||||||
def __contains__(self, propname):
|
def __contains__(self, propname):
|
||||||
return propname in self._properties
|
return propname in self._properties
|
||||||
|
@ -200,15 +201,6 @@ class Settings(object):
|
||||||
self._p_ = __import__(import_lib, globals(), locals(), ['Settings'],
|
self._p_ = __import__(import_lib, globals(), locals(), ['Settings'],
|
||||||
-1).Settings(storage)
|
-1).Settings(storage)
|
||||||
|
|
||||||
def _getkey(self, opt):
|
|
||||||
if self._p_.key_is_path:
|
|
||||||
if opt is None:
|
|
||||||
return '_none'
|
|
||||||
else:
|
|
||||||
return self._get_opt_path(opt)
|
|
||||||
else:
|
|
||||||
return opt
|
|
||||||
|
|
||||||
#____________________________________________________________
|
#____________________________________________________________
|
||||||
# properties methods
|
# properties methods
|
||||||
def __contains__(self, propname):
|
def __contains__(self, propname):
|
||||||
|
@ -219,7 +211,14 @@ class Settings(object):
|
||||||
return str(list(self._getproperties()))
|
return str(list(self._getproperties()))
|
||||||
|
|
||||||
def __getitem__(self, opt):
|
def __getitem__(self, opt):
|
||||||
return Property(self, self._getproperties(opt), opt)
|
if opt is None:
|
||||||
|
path = None
|
||||||
|
else:
|
||||||
|
path = self._get_opt_path(opt)
|
||||||
|
return self._getitem(opt, path)
|
||||||
|
|
||||||
|
def _getitem(self, opt, path):
|
||||||
|
return Property(self, self._getproperties(opt, path), opt, path)
|
||||||
|
|
||||||
def __setitem__(self, opt, value):
|
def __setitem__(self, opt, value):
|
||||||
raise ValueError('you must only append/remove properties')
|
raise ValueError('you must only append/remove properties')
|
||||||
|
@ -231,26 +230,32 @@ class Settings(object):
|
||||||
if all_properties:
|
if all_properties:
|
||||||
self._p_.reset_all_propertives()
|
self._p_.reset_all_propertives()
|
||||||
else:
|
else:
|
||||||
self._p_.reset_properties(self._getkey(opt))
|
if opt is None:
|
||||||
|
path = None
|
||||||
|
else:
|
||||||
|
path = self._get_opt_path(opt)
|
||||||
|
self._p_.reset_properties(path)
|
||||||
self.context.cfgimpl_reset_cache()
|
self.context.cfgimpl_reset_cache()
|
||||||
|
|
||||||
def _getproperties(self, opt=None, is_apply_req=True):
|
def _getproperties(self, opt=None, path=None, is_apply_req=True):
|
||||||
if opt is None:
|
if opt is None:
|
||||||
props = self._p_.getproperties(self._getkey(opt), default_properties)
|
props = self._p_.getproperties(path, default_properties)
|
||||||
else:
|
else:
|
||||||
|
if path is None:
|
||||||
|
raise ValueError(_('if opt is not None, path should not be None in _getproperties'))
|
||||||
ntime = None
|
ntime = None
|
||||||
if self._p_.hascache('property', self._getkey(opt)):
|
if self._p_.hascache('property', path):
|
||||||
ntime = time()
|
ntime = time()
|
||||||
is_cached, props = self._p_.getcache('property', self._getkey(opt), ntime)
|
is_cached, props = self._p_.getcache('property', path, ntime)
|
||||||
if is_cached:
|
if is_cached:
|
||||||
return props
|
return props
|
||||||
if is_apply_req:
|
if is_apply_req:
|
||||||
self.apply_requires(opt)
|
self.apply_requires(opt, path)
|
||||||
props = self._p_.getproperties(self._getkey(opt), opt._properties)
|
props = self._p_.getproperties(path, opt._properties)
|
||||||
if 'expire' in self:
|
if 'expire' in self:
|
||||||
if ntime is None:
|
if ntime is None:
|
||||||
ntime = time()
|
ntime = time()
|
||||||
self._p_.setcache('property', self._getkey(opt), props, ntime + expires_time)
|
self._p_.setcache('property', path, props, ntime + expires_time)
|
||||||
return props
|
return props
|
||||||
|
|
||||||
def append(self, propname):
|
def append(self, propname):
|
||||||
|
@ -261,21 +266,21 @@ class Settings(object):
|
||||||
"deletes property propname in the Config's properties attribute"
|
"deletes property propname in the Config's properties attribute"
|
||||||
Property(self, self._getproperties()).remove(propname)
|
Property(self, self._getproperties()).remove(propname)
|
||||||
|
|
||||||
def _setproperties(self, properties, opt=None):
|
def _setproperties(self, properties, opt, path):
|
||||||
"""save properties for specified opt
|
"""save properties for specified opt
|
||||||
(never save properties if same has option properties)
|
(never save properties if same has option properties)
|
||||||
"""
|
"""
|
||||||
if opt is None:
|
if opt is None:
|
||||||
self._p_.setproperties(self._getkey(opt), properties)
|
self._p_.setproperties(path, properties)
|
||||||
else:
|
else:
|
||||||
if set(opt._properties) == properties:
|
if set(opt._properties) == properties:
|
||||||
self._p_.reset_properties(self._getkey(opt))
|
self._p_.reset_properties(path)
|
||||||
else:
|
else:
|
||||||
self._p_.setproperties(self._getkey(opt), properties)
|
self._p_.setproperties(path, properties)
|
||||||
self.context.cfgimpl_reset_cache()
|
self.context.cfgimpl_reset_cache()
|
||||||
|
|
||||||
#____________________________________________________________
|
#____________________________________________________________
|
||||||
def validate_properties(self, opt_or_descr, is_descr, is_write,
|
def validate_properties(self, opt_or_descr, is_descr, is_write, path,
|
||||||
value=None, force_permissive=False,
|
value=None, force_permissive=False,
|
||||||
force_properties=None):
|
force_properties=None):
|
||||||
"""
|
"""
|
||||||
|
@ -291,9 +296,9 @@ class Settings(object):
|
||||||
property)
|
property)
|
||||||
"""
|
"""
|
||||||
# opt properties
|
# opt properties
|
||||||
properties = copy(self._getproperties(opt_or_descr))
|
properties = copy(self._getproperties(opt_or_descr, path))
|
||||||
# remove opt permissive
|
# remove opt permissive
|
||||||
properties -= self._p_.getpermissive(self._getkey(opt_or_descr))
|
properties -= self._p_.getpermissive(path)
|
||||||
# remove global permissive if need
|
# remove global permissive if need
|
||||||
self_properties = copy(self._getproperties())
|
self_properties = copy(self._getproperties())
|
||||||
if force_permissive is True or 'permissive' in self_properties:
|
if force_permissive is True or 'permissive' in self_properties:
|
||||||
|
@ -332,11 +337,10 @@ class Settings(object):
|
||||||
"").format(opt_or_descr._name,
|
"").format(opt_or_descr._name,
|
||||||
str(props)), props)
|
str(props)), props)
|
||||||
|
|
||||||
# XXX should rename it to setpermissive, but kept for retro compatibility
|
def setpermissive(self, permissive, path=None):
|
||||||
def set_permissive(self, permissive, opt=None):
|
|
||||||
if not isinstance(permissive, tuple):
|
if not isinstance(permissive, tuple):
|
||||||
raise TypeError(_('permissive must be a tuple'))
|
raise TypeError(_('permissive must be a tuple'))
|
||||||
self._p_.setpermissive(self._getkey(opt), permissive)
|
self._p_.setpermissive(path, permissive)
|
||||||
|
|
||||||
#____________________________________________________________
|
#____________________________________________________________
|
||||||
def setowner(self, owner):
|
def setowner(self, owner):
|
||||||
|
@ -369,28 +373,27 @@ class Settings(object):
|
||||||
else:
|
else:
|
||||||
self._p_.reset_all_cache('property')
|
self._p_.reset_all_cache('property')
|
||||||
|
|
||||||
def apply_requires(self, opt):
|
def apply_requires(self, opt, path):
|
||||||
"carries out the jit (just in time requirements between options"
|
"carries out the jit (just in time requirements between options"
|
||||||
if opt._requires is None:
|
if opt._requires is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
# filters the callbacks
|
# filters the callbacks
|
||||||
setting = Property(self, self._getproperties(opt, False), opt)
|
setting = Property(self, self._getproperties(opt, path, False), opt, path=path)
|
||||||
descr = self.context.cfgimpl_get_description()
|
descr = self.context.cfgimpl_get_description()
|
||||||
optpath = descr.impl_get_path_by_opt(opt)
|
|
||||||
for requires in opt._requires:
|
for requires in opt._requires:
|
||||||
matches = False
|
matches = False
|
||||||
for require in requires:
|
for require in requires:
|
||||||
option, expected, action, inverse, \
|
option, expected, action, inverse, \
|
||||||
transitive, same_action = require
|
transitive, same_action = require
|
||||||
path = descr.impl_get_path_by_opt(option)
|
reqpath = self._get_opt_path(option)
|
||||||
if path == optpath or path.startswith(optpath + '.'):
|
if reqpath == path or reqpath.startswith(path + '.'):
|
||||||
raise RequirementError(_("malformed requirements "
|
raise RequirementError(_("malformed requirements "
|
||||||
"imbrication detected for option:"
|
"imbrication detected for option:"
|
||||||
" '{0}' with requirement on: "
|
" '{0}' with requirement on: "
|
||||||
"'{1}'").format(optpath, path))
|
"'{1}'").format(path, reqpath))
|
||||||
try:
|
try:
|
||||||
value = self.context._getattr(path, force_permissive=True)
|
value = self.context._getattr(reqpath, force_permissive=True)
|
||||||
except PropertiesOptionError, err:
|
except PropertiesOptionError, err:
|
||||||
if not transitive:
|
if not transitive:
|
||||||
continue
|
continue
|
||||||
|
@ -400,14 +403,14 @@ class Settings(object):
|
||||||
"requirement's property "
|
"requirement's property "
|
||||||
"error: "
|
"error: "
|
||||||
"{1} {2}").format(opt._name,
|
"{1} {2}").format(opt._name,
|
||||||
path,
|
reqpath,
|
||||||
properties))
|
properties))
|
||||||
# transitive action, force expected
|
# transitive action, force expected
|
||||||
value = expected[0]
|
value = expected[0]
|
||||||
inverse = False
|
inverse = False
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
raise AttributeError(_("required option not found: "
|
raise AttributeError(_("required option not found: "
|
||||||
"{0}").format(path))
|
"{0}").format(reqpath))
|
||||||
if (not inverse and
|
if (not inverse and
|
||||||
value in expected or
|
value in expected or
|
||||||
inverse and value not in expected):
|
inverse and value not in expected):
|
||||||
|
|
|
@ -32,21 +32,21 @@ class Settings(Cache):
|
||||||
super(Settings, self).__init__()
|
super(Settings, self).__init__()
|
||||||
|
|
||||||
# propertives
|
# propertives
|
||||||
def setproperties(self, opt, properties):
|
def setproperties(self, path, properties):
|
||||||
self._properties[opt] = properties
|
self._properties[path] = properties
|
||||||
|
|
||||||
def getproperties(self, opt, default_properties):
|
def getproperties(self, path, default_properties):
|
||||||
return self._properties.get(opt, set(default_properties))
|
return self._properties.get(path, set(default_properties))
|
||||||
|
|
||||||
def hasproperties(self, opt):
|
def hasproperties(self, path):
|
||||||
return opt in self._properties
|
return path in self._properties
|
||||||
|
|
||||||
def reset_all_propertives(self):
|
def reset_all_propertives(self):
|
||||||
self._properties.clear()
|
self._properties.clear()
|
||||||
|
|
||||||
def reset_properties(self, opt):
|
def reset_properties(self, path):
|
||||||
try:
|
try:
|
||||||
del(self._properties[opt])
|
del(self._properties[path])
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -54,8 +54,8 @@ class Settings(Cache):
|
||||||
return self._properties
|
return self._properties
|
||||||
|
|
||||||
# permissive
|
# permissive
|
||||||
def setpermissive(self, opt, permissive):
|
def setpermissive(self, path, permissive):
|
||||||
self._permissives[opt] = frozenset(permissive)
|
self._permissives[path] = frozenset(permissive)
|
||||||
|
|
||||||
def getpermissive(self, opt=None):
|
def getpermissive(self, path=None):
|
||||||
return self._permissives.get(opt, frozenset())
|
return self._permissives.get(path, frozenset())
|
||||||
|
|
|
@ -36,22 +36,22 @@ class Cache(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._cache = {}
|
self._cache = {}
|
||||||
|
|
||||||
def setcache(self, cache_type, opt, val, time):
|
def setcache(self, cache_type, path, val, time):
|
||||||
self._cache[opt] = (val, time)
|
self._cache[path] = (val, time)
|
||||||
|
|
||||||
def getcache(self, cache_type, opt, exp):
|
def getcache(self, cache_type, path, exp):
|
||||||
value, created = self._cache[opt]
|
value, created = self._cache[path]
|
||||||
if exp < created:
|
if exp < created:
|
||||||
return True, value
|
return True, value
|
||||||
return False, None
|
return False, None
|
||||||
|
|
||||||
def hascache(self, cache_type, opt):
|
def hascache(self, cache_type, path):
|
||||||
""" option is in the cache
|
""" path is in the cache
|
||||||
|
|
||||||
:param cache_type: value | property
|
:param cache_type: value | property
|
||||||
:param opt: the key (typically, the option object)
|
:param path: the path's option
|
||||||
"""
|
"""
|
||||||
return opt in self._cache
|
return path in self._cache
|
||||||
|
|
||||||
def reset_expired_cache(self, cache_type, exp):
|
def reset_expired_cache(self, cache_type, exp):
|
||||||
keys = self._cache.keys()
|
keys = self._cache.keys()
|
||||||
|
@ -66,6 +66,6 @@ class Cache(object):
|
||||||
|
|
||||||
def get_cached(self, cache_type, context):
|
def get_cached(self, cache_type, context):
|
||||||
"""return all values in a dictionary
|
"""return all values in a dictionary
|
||||||
example: {option1: ('value1', 'time1'), option2: ('value2', 'time2')}
|
example: {'path1': ('value1', 'time1'), 'path2': ('value2', 'time2')}
|
||||||
"""
|
"""
|
||||||
return self._cache
|
return self._cache
|
||||||
|
|
|
@ -32,43 +32,43 @@ class Values(Cache):
|
||||||
super(Values, self).__init__()
|
super(Values, self).__init__()
|
||||||
|
|
||||||
# value
|
# value
|
||||||
def setvalue(self, opt, value, owner):
|
def setvalue(self, path, value, owner):
|
||||||
"""set value for an option
|
"""set value for a path
|
||||||
a specified value must be associated to an owner
|
a specified value must be associated to an owner
|
||||||
"""
|
"""
|
||||||
self._values[opt] = (owner, value)
|
self._values[path] = (owner, value)
|
||||||
|
|
||||||
def getvalue(self, opt):
|
def getvalue(self, path):
|
||||||
"""get value for an option
|
"""get value for a path
|
||||||
return: only value, not the owner
|
return: only value, not the owner
|
||||||
"""
|
"""
|
||||||
return self._values[opt][1]
|
return self._values[path][1]
|
||||||
|
|
||||||
def hasvalue(self, opt):
|
def hasvalue(self, path):
|
||||||
"""if opt has a value
|
"""if path has a value
|
||||||
return: boolean
|
return: boolean
|
||||||
"""
|
"""
|
||||||
return opt in self._values
|
return path in self._values
|
||||||
|
|
||||||
def resetvalue(self, opt):
|
def resetvalue(self, path):
|
||||||
"""remove value means delete value in storage
|
"""remove value means delete value in storage
|
||||||
"""
|
"""
|
||||||
del(self._values[opt])
|
del(self._values[path])
|
||||||
|
|
||||||
def get_modified_values(self):
|
def get_modified_values(self):
|
||||||
"""return all values in a dictionary
|
"""return all values in a dictionary
|
||||||
example: {option1: (owner, 'value1'), option2: (owner, 'value2')}
|
example: {'path1': (owner, 'value1'), 'path2': (owner, 'value2')}
|
||||||
"""
|
"""
|
||||||
return self._values
|
return self._values
|
||||||
|
|
||||||
# owner
|
# owner
|
||||||
def setowner(self, opt, owner):
|
def setowner(self, path, owner):
|
||||||
"""change owner for an option
|
"""change owner for a path
|
||||||
"""
|
"""
|
||||||
self._values[opt] = (owner, self._values[opt][1])
|
self._values[path] = (owner, self._values[path][1])
|
||||||
|
|
||||||
def getowner(self, opt, default):
|
def getowner(self, path, default):
|
||||||
"""get owner for an option
|
"""get owner for a path
|
||||||
return: owner object
|
return: owner object
|
||||||
"""
|
"""
|
||||||
return self._values.get(opt, (default, None))[0]
|
return self._values.get(path, (default, None))[0]
|
||||||
|
|
|
@ -46,15 +46,6 @@ class Values(object):
|
||||||
self._p_ = __import__(import_lib, globals(), locals(), ['Values'],
|
self._p_ = __import__(import_lib, globals(), locals(), ['Values'],
|
||||||
-1).Values(storage)
|
-1).Values(storage)
|
||||||
|
|
||||||
def _getkey(self, opt):
|
|
||||||
"""depends on the storage utility.
|
|
||||||
typically, the option's path in the parent `Config` or `SubConfig`
|
|
||||||
"""
|
|
||||||
if self._p_.key_is_path:
|
|
||||||
return self._get_opt_path(opt)
|
|
||||||
else:
|
|
||||||
return opt
|
|
||||||
|
|
||||||
def _getdefault(self, opt):
|
def _getdefault(self, opt):
|
||||||
"""
|
"""
|
||||||
actually retrieves the default value
|
actually retrieves the default value
|
||||||
|
@ -71,24 +62,23 @@ class Values(object):
|
||||||
else:
|
else:
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def _getvalue(self, opt, validate=True):
|
def _getvalue(self, opt, path, validate=True):
|
||||||
"""actually retrieves the value
|
"""actually retrieves the value
|
||||||
|
|
||||||
:param opt: the `option.Option()` object
|
:param opt: the `option.Option()` object
|
||||||
:returns: the option's value (or the default value if not set)
|
:returns: the option's value (or the default value if not set)
|
||||||
"""
|
"""
|
||||||
key = self._getkey(opt)
|
if not self._p_.hasvalue(path):
|
||||||
if not self._p_.hasvalue(key):
|
|
||||||
# if there is no value
|
# if there is no value
|
||||||
value = self._getdefault(opt)
|
value = self._getdefault(opt)
|
||||||
if opt.impl_is_multi():
|
if opt.impl_is_multi():
|
||||||
value = Multi(value, self.context, opt, validate)
|
value = Multi(value, self.context, opt, path, validate)
|
||||||
else:
|
else:
|
||||||
# if there is a value
|
# if there is a value
|
||||||
value = self._p_.getvalue(key)
|
value = self._p_.getvalue(path)
|
||||||
if opt.impl_is_multi() and not isinstance(value, Multi):
|
if opt.impl_is_multi() and not isinstance(value, Multi):
|
||||||
# load value so don't need to validate if is not a Multi
|
# load value so don't need to validate if is not a Multi
|
||||||
value = Multi(value, self.context, opt, validate=False)
|
value = Multi(value, self.context, opt, path, validate=False)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def get_modified_values(self):
|
def get_modified_values(self):
|
||||||
|
@ -101,15 +91,20 @@ class Values(object):
|
||||||
|
|
||||||
:param opt: the `option.Option()` object
|
:param opt: the `option.Option()` object
|
||||||
"""
|
"""
|
||||||
return self._p_.hasvalue('value', self._getkey(opt))
|
path = self._get_opt_path(opt)
|
||||||
|
self._contains(path)
|
||||||
|
|
||||||
|
def _contains(self, path):
|
||||||
|
return self._p_.hasvalue('value', path)
|
||||||
|
|
||||||
def __delitem__(self, opt):
|
def __delitem__(self, opt):
|
||||||
"""overrides the builtins `del()` instructions"""
|
"""overrides the builtins `del()` instructions"""
|
||||||
self.reset(opt)
|
self.reset(opt)
|
||||||
|
|
||||||
def reset(self, opt):
|
def reset(self, opt, path=None):
|
||||||
key = self._getkey(opt)
|
if path is None:
|
||||||
if self._p_.hasvalue(key):
|
path = self._get_opt_path(opt)
|
||||||
|
if self._p_.hasvalue(path):
|
||||||
setting = self.context.cfgimpl_get_settings()
|
setting = self.context.cfgimpl_get_settings()
|
||||||
opt.impl_validate(opt.impl_getdefault(), self.context,
|
opt.impl_validate(opt.impl_getdefault(), self.context,
|
||||||
'validator' in setting)
|
'validator' in setting)
|
||||||
|
@ -118,7 +113,7 @@ class Values(object):
|
||||||
opt.impl_get_multitype() == multitypes.master):
|
opt.impl_get_multitype() == multitypes.master):
|
||||||
for slave in opt.impl_get_master_slaves():
|
for slave in opt.impl_get_master_slaves():
|
||||||
self.reset(slave)
|
self.reset(slave)
|
||||||
self._p_.resetvalue(key)
|
self._p_.resetvalue(path)
|
||||||
|
|
||||||
def _isempty(self, opt, value):
|
def _isempty(self, opt, value):
|
||||||
"convenience method to know if an option is empty"
|
"convenience method to know if an option is empty"
|
||||||
|
@ -150,30 +145,31 @@ class Values(object):
|
||||||
"enables us to use the pythonic dictionnary-like access to values"
|
"enables us to use the pythonic dictionnary-like access to values"
|
||||||
return self.getitem(opt)
|
return self.getitem(opt)
|
||||||
|
|
||||||
def getitem(self, opt, validate=True, force_permissive=False,
|
def getitem(self, opt, path=None, validate=True, force_permissive=False,
|
||||||
force_properties=None, validate_properties=True):
|
force_properties=None, validate_properties=True):
|
||||||
ntime = None
|
ntime = None
|
||||||
key = self._getkey(opt)
|
if path is None:
|
||||||
if self._p_.hascache('value', self._getkey(opt)):
|
path = self._get_opt_path(opt)
|
||||||
|
if self._p_.hascache('value', path):
|
||||||
ntime = time()
|
ntime = time()
|
||||||
is_cached, value = self._p_.getcache('value', key, ntime)
|
is_cached, value = self._p_.getcache('value', path, ntime)
|
||||||
if is_cached:
|
if is_cached:
|
||||||
if opt.impl_is_multi() and not isinstance(value, Multi):
|
if opt.impl_is_multi() and not isinstance(value, Multi):
|
||||||
#load value so don't need to validate if is not a Multi
|
#load value so don't need to validate if is not a Multi
|
||||||
value = Multi(value, self.context, opt, validate=False)
|
value = Multi(value, self.context, opt, path, validate=False)
|
||||||
return value
|
return value
|
||||||
val = self._getitem(opt, validate, force_permissive, force_properties,
|
val = self._getitem(opt, path, validate, force_permissive, force_properties,
|
||||||
validate_properties)
|
validate_properties)
|
||||||
if 'expire' in self.context.cfgimpl_get_settings() and validate and \
|
if 'expire' in self.context.cfgimpl_get_settings() and validate and \
|
||||||
validate_properties and force_permissive is False and \
|
validate_properties and force_permissive is False and \
|
||||||
force_properties is None:
|
force_properties is None:
|
||||||
if ntime is None:
|
if ntime is None:
|
||||||
ntime = time()
|
ntime = time()
|
||||||
self._p_.setcache('value', key, val, ntime + expires_time)
|
self._p_.setcache('value', path, val, ntime + expires_time)
|
||||||
|
|
||||||
return val
|
return val
|
||||||
|
|
||||||
def _getitem(self, opt, validate, force_permissive, force_properties,
|
def _getitem(self, opt, path, validate, force_permissive, force_properties,
|
||||||
validate_properties):
|
validate_properties):
|
||||||
# options with callbacks
|
# options with callbacks
|
||||||
setting = self.context.cfgimpl_get_settings()
|
setting = self.context.cfgimpl_get_settings()
|
||||||
|
@ -181,7 +177,7 @@ class Values(object):
|
||||||
# if value is callback and is not set
|
# if value is callback and is not set
|
||||||
# or frozen with force_default_on_freeze
|
# or frozen with force_default_on_freeze
|
||||||
if opt.impl_has_callback() and (
|
if opt.impl_has_callback() and (
|
||||||
self.is_default_owner(opt) or
|
self._is_default_owner(path) or
|
||||||
(is_frozen and 'force_default_on_freeze' in setting[opt])):
|
(is_frozen and 'force_default_on_freeze' in setting[opt])):
|
||||||
no_value_slave = False
|
no_value_slave = False
|
||||||
if (opt.impl_is_multi() and
|
if (opt.impl_is_multi() and
|
||||||
|
@ -200,53 +196,55 @@ class Values(object):
|
||||||
if not isinstance(value, list):
|
if not isinstance(value, list):
|
||||||
value = [value for i in range(lenmaster)]
|
value = [value for i in range(lenmaster)]
|
||||||
if opt.impl_is_multi():
|
if opt.impl_is_multi():
|
||||||
value = Multi(value, self.context, opt, validate)
|
value = Multi(value, self.context, opt, path, validate)
|
||||||
# suppress value if already set
|
# suppress value if already set
|
||||||
self.reset(opt)
|
self.reset(opt, path)
|
||||||
# frozen and force default
|
# frozen and force default
|
||||||
elif is_frozen and 'force_default_on_freeze' in setting[opt]:
|
elif is_frozen and 'force_default_on_freeze' in setting[opt]:
|
||||||
value = self._getdefault(opt)
|
value = self._getdefault(opt)
|
||||||
if opt.impl_is_multi():
|
if opt.impl_is_multi():
|
||||||
value = Multi(value, self.context, opt, validate)
|
value = Multi(value, self.context, opt, path, validate)
|
||||||
else:
|
else:
|
||||||
value = self._getvalue(opt, validate)
|
value = self._getvalue(opt, path, validate)
|
||||||
if validate:
|
if validate:
|
||||||
opt.impl_validate(value, self.context, 'validator' in setting)
|
opt.impl_validate(value, self.context, 'validator' in setting)
|
||||||
if self.is_default_owner(opt) and \
|
if self._is_default_owner(path) and \
|
||||||
'force_store_value' in setting[opt]:
|
'force_store_value' in setting[opt]:
|
||||||
self.setitem(opt, value, is_write=False)
|
self.setitem(opt, value, path, is_write=False)
|
||||||
if validate_properties:
|
if validate_properties:
|
||||||
setting.validate_properties(opt, False, False, value=value,
|
setting.validate_properties(opt, False, False, value=value, path=path,
|
||||||
force_permissive=force_permissive,
|
force_permissive=force_permissive,
|
||||||
force_properties=force_properties)
|
force_properties=force_properties)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def __setitem__(self, opt, value):
|
def __setitem__(self, opt, value):
|
||||||
self.setitem(opt, value)
|
path = self._get_opt_path(opt)
|
||||||
|
self.setitem(opt, value, path)
|
||||||
|
|
||||||
def setitem(self, opt, value, force_permissive=False, is_write=True):
|
def setitem(self, opt, value, path, force_permissive=False,
|
||||||
|
is_write=True):
|
||||||
# is_write is, for example, used with "force_store_value"
|
# is_write is, for example, used with "force_store_value"
|
||||||
# user didn't change value, so not write
|
# user didn't change value, so not write
|
||||||
# valid opt
|
# valid opt
|
||||||
opt.impl_validate(value, self.context,
|
opt.impl_validate(value, self.context,
|
||||||
'validator' in self.context.cfgimpl_get_settings())
|
'validator' in self.context.cfgimpl_get_settings())
|
||||||
if opt.impl_is_multi() and not isinstance(value, Multi):
|
if opt.impl_is_multi() and not isinstance(value, Multi):
|
||||||
value = Multi(value, self.context, opt)
|
value = Multi(value, self.context, opt, path)
|
||||||
self._setvalue(opt, value, force_permissive=force_permissive,
|
self._setvalue(opt, path, value, force_permissive=force_permissive,
|
||||||
is_write=is_write)
|
is_write=is_write)
|
||||||
|
|
||||||
def _setvalue(self, opt, value, force_permissive=False,
|
def _setvalue(self, opt, path, value, force_permissive=False,
|
||||||
force_properties=None,
|
force_properties=None,
|
||||||
is_write=True, validate_properties=True):
|
is_write=True, validate_properties=True):
|
||||||
self.context.cfgimpl_reset_cache()
|
self.context.cfgimpl_reset_cache()
|
||||||
if validate_properties:
|
if validate_properties:
|
||||||
setting = self.context.cfgimpl_get_settings()
|
setting = self.context.cfgimpl_get_settings()
|
||||||
setting.validate_properties(opt, False, is_write,
|
setting.validate_properties(opt, False, is_write,
|
||||||
value=value,
|
value=value, path=path,
|
||||||
force_permissive=force_permissive,
|
force_permissive=force_permissive,
|
||||||
force_properties=force_properties)
|
force_properties=force_properties)
|
||||||
owner = self.context.cfgimpl_get_settings().getowner()
|
owner = self.context.cfgimpl_get_settings().getowner()
|
||||||
self._p_.setvalue(self._getkey(opt), value, owner)
|
self._p_.setvalue(path, value, owner)
|
||||||
|
|
||||||
def getowner(self, opt):
|
def getowner(self, opt):
|
||||||
"""
|
"""
|
||||||
|
@ -257,10 +255,14 @@ class Values(object):
|
||||||
"""
|
"""
|
||||||
if isinstance(opt, SymLinkOption):
|
if isinstance(opt, SymLinkOption):
|
||||||
opt = opt._opt
|
opt = opt._opt
|
||||||
owner = self._p_.getowner(self._getkey(opt), owners.default)
|
path = self._get_opt_path(opt)
|
||||||
|
return self._getowner(path)
|
||||||
|
|
||||||
|
def _getowner(self, path):
|
||||||
|
owner = self._p_.getowner(path, owners.default)
|
||||||
meta = self.context.cfgimpl_get_meta()
|
meta = self.context.cfgimpl_get_meta()
|
||||||
if owner is owners.default and meta is not None:
|
if owner is owners.default and meta is not None:
|
||||||
owner = meta.cfgimpl_get_values().getowner(opt)
|
owner = meta.cfgimpl_get_values()._getowner(path)
|
||||||
return owner
|
return owner
|
||||||
|
|
||||||
def setowner(self, opt, owner):
|
def setowner(self, opt, owner):
|
||||||
|
@ -272,10 +274,15 @@ class Values(object):
|
||||||
"""
|
"""
|
||||||
if not isinstance(owner, owners.Owner):
|
if not isinstance(owner, owners.Owner):
|
||||||
raise TypeError(_("invalid generic owner {0}").format(str(owner)))
|
raise TypeError(_("invalid generic owner {0}").format(str(owner)))
|
||||||
if self.getowner(opt) == owners.default:
|
|
||||||
|
path = self._get_opt_path(opt)
|
||||||
|
self._setowner(path, owner)
|
||||||
|
|
||||||
|
def _setowner(self, path, owner):
|
||||||
|
if self._getowner(path) == owners.default:
|
||||||
raise ConfigError(_('no value for {0} cannot change owner to {1}'
|
raise ConfigError(_('no value for {0} cannot change owner to {1}'
|
||||||
'').format(opt._name, owner))
|
'').format(path, owner))
|
||||||
self._p_.setowner(self._getkey(opt), owner)
|
self._p_.setowner(path, owner)
|
||||||
|
|
||||||
def is_default_owner(self, opt):
|
def is_default_owner(self, opt):
|
||||||
"""
|
"""
|
||||||
|
@ -283,7 +290,11 @@ class Values(object):
|
||||||
(not the toplevel config)
|
(not the toplevel config)
|
||||||
:return: boolean
|
:return: boolean
|
||||||
"""
|
"""
|
||||||
return self.getowner(opt) == owners.default
|
path = self._get_opt_path(opt)
|
||||||
|
return self._is_default_owner(path)
|
||||||
|
|
||||||
|
def _is_default_owner(self, path):
|
||||||
|
return self._getowner(path) == owners.default
|
||||||
|
|
||||||
def reset_cache(self, only_expired):
|
def reset_cache(self, only_expired):
|
||||||
"""
|
"""
|
||||||
|
@ -310,15 +321,16 @@ class Values(object):
|
||||||
class Multi(list):
|
class Multi(list):
|
||||||
"""multi options values container
|
"""multi options values container
|
||||||
that support item notation for the values of multi options"""
|
that support item notation for the values of multi options"""
|
||||||
__slots__ = ('opt', 'context')
|
__slots__ = ('opt', 'path', 'context')
|
||||||
|
|
||||||
def __init__(self, value, context, opt, validate=True):
|
def __init__(self, value, context, opt, path, validate=True):
|
||||||
"""
|
"""
|
||||||
:param value: the Multi wraps a list value
|
:param value: the Multi wraps a list value
|
||||||
:param context: the home config that has the values
|
:param context: the home config that has the values
|
||||||
:param opt: the option object that have this Multi value
|
:param opt: the option object that have this Multi value
|
||||||
"""
|
"""
|
||||||
self.opt = opt
|
self.opt = opt
|
||||||
|
self.path = path
|
||||||
self.context = context
|
self.context = context
|
||||||
if not isinstance(value, list):
|
if not isinstance(value, list):
|
||||||
value = [value]
|
value = [value]
|
||||||
|
@ -337,7 +349,7 @@ class Multi(list):
|
||||||
valuelen = len(value)
|
valuelen = len(value)
|
||||||
if valuelen > masterlen or (valuelen < masterlen and
|
if valuelen > masterlen or (valuelen < masterlen and
|
||||||
not self.context.cfgimpl_get_values(
|
not self.context.cfgimpl_get_values(
|
||||||
).is_default_owner(self.opt)):
|
)._is_default_owner(self.path)):
|
||||||
raise SlaveError(_("invalid len for the slave: {0}"
|
raise SlaveError(_("invalid len for the slave: {0}"
|
||||||
" which has {1} as master").format(
|
" which has {1} as master").format(
|
||||||
self.opt._name, masterp))
|
self.opt._name, masterp))
|
||||||
|
@ -351,8 +363,9 @@ class Multi(list):
|
||||||
masterlen = len(value)
|
masterlen = len(value)
|
||||||
values = self.context.cfgimpl_get_values()
|
values = self.context.cfgimpl_get_values()
|
||||||
for slave in self.opt._master_slaves:
|
for slave in self.opt._master_slaves:
|
||||||
if not values.is_default_owner(slave):
|
path = values._get_opt_path(slave)
|
||||||
value_slave = values._getvalue(slave)
|
if not values._is_default_owner(path):
|
||||||
|
value_slave = values._getvalue(slave, path)
|
||||||
if len(value_slave) > masterlen:
|
if len(value_slave) > masterlen:
|
||||||
raise SlaveError(_("invalid len for the master: {0}"
|
raise SlaveError(_("invalid len for the master: {0}"
|
||||||
" which has {1} as slave with"
|
" which has {1} as slave with"
|
||||||
|
@ -363,11 +376,11 @@ class Multi(list):
|
||||||
value_slave.append(slave.impl_getdefault_multi(),
|
value_slave.append(slave.impl_getdefault_multi(),
|
||||||
force=True)
|
force=True)
|
||||||
|
|
||||||
def __setitem__(self, key, value):
|
def __setitem__(self, path, value):
|
||||||
self._validate(value)
|
self._validate(value)
|
||||||
#assume not checking mandatory property
|
#assume not checking mandatory property
|
||||||
super(Multi, self).__setitem__(key, value)
|
super(Multi, self).__setitem__(path, value)
|
||||||
self.context.cfgimpl_get_values()._setvalue(self.opt, self)
|
self.context.cfgimpl_get_values()._setvalue(self.opt, path, self)
|
||||||
|
|
||||||
def append(self, value, force=False):
|
def append(self, value, force=False):
|
||||||
"""the list value can be updated (appened)
|
"""the list value can be updated (appened)
|
||||||
|
@ -386,21 +399,26 @@ class Multi(list):
|
||||||
value = None
|
value = None
|
||||||
self._validate(value)
|
self._validate(value)
|
||||||
super(Multi, self).append(value)
|
super(Multi, self).append(value)
|
||||||
self.context.cfgimpl_get_values()._setvalue(self.opt, self, validate_properties=not force)
|
self.context.cfgimpl_get_values()._setvalue(self.opt, self.path, self, validate_properties=not force)
|
||||||
if not force and self.opt.impl_get_multitype() == multitypes.master:
|
if not force and self.opt.impl_get_multitype() == multitypes.master:
|
||||||
for slave in self.opt.impl_get_master_slaves():
|
for slave in self.opt.impl_get_master_slaves():
|
||||||
if not values.is_default_owner(slave):
|
path = values._get_opt_path(slave)
|
||||||
|
if not values._is_default_owner(path):
|
||||||
if slave.impl_has_callback():
|
if slave.impl_has_callback():
|
||||||
index = self.__len__() - 1
|
index = self.__len__() - 1
|
||||||
dvalue = values._getcallback_value(slave, index=index)
|
dvalue = values._getcallback_value(slave, index=index)
|
||||||
else:
|
else:
|
||||||
dvalue = slave.impl_getdefault_multi()
|
dvalue = slave.impl_getdefault_multi()
|
||||||
old_value = values.getitem(slave, validate_properties=False)
|
old_value = values.getitem(slave, path,
|
||||||
|
validate_properties=False)
|
||||||
if len(old_value) < self.__len__():
|
if len(old_value) < self.__len__():
|
||||||
values.getitem(slave, validate_properties=False).append(
|
values.getitem(slave, path,
|
||||||
|
validate_properties=False).append(
|
||||||
dvalue, force=True)
|
dvalue, force=True)
|
||||||
else:
|
else:
|
||||||
values.getitem(slave, validate_properties=False)[index] = dvalue
|
values.getitem(slave, path,
|
||||||
|
validate_properties=False)[
|
||||||
|
index] = dvalue
|
||||||
|
|
||||||
def sort(self, cmp=None, key=None, reverse=False):
|
def sort(self, cmp=None, key=None, reverse=False):
|
||||||
if self.opt.impl_get_multitype() in [multitypes.slave,
|
if self.opt.impl_get_multitype() in [multitypes.slave,
|
||||||
|
@ -408,7 +426,7 @@ class Multi(list):
|
||||||
raise SlaveError(_("cannot sort multi option {0} if master or slave"
|
raise SlaveError(_("cannot sort multi option {0} if master or slave"
|
||||||
"").format(self.opt._name))
|
"").format(self.opt._name))
|
||||||
super(Multi, self).sort(cmp=cmp, key=key, reverse=reverse)
|
super(Multi, self).sort(cmp=cmp, key=key, reverse=reverse)
|
||||||
self.context.cfgimpl_get_values()._setvalue(self.opt, self)
|
self.context.cfgimpl_get_values()._setvalue(self.opt, self.path, self)
|
||||||
|
|
||||||
def reverse(self):
|
def reverse(self):
|
||||||
if self.opt.impl_get_multitype() in [multitypes.slave,
|
if self.opt.impl_get_multitype() in [multitypes.slave,
|
||||||
|
@ -416,7 +434,7 @@ class Multi(list):
|
||||||
raise SlaveError(_("cannot reverse multi option {0} if master or "
|
raise SlaveError(_("cannot reverse multi option {0} if master or "
|
||||||
"slave").format(self.opt._name))
|
"slave").format(self.opt._name))
|
||||||
super(Multi, self).reverse()
|
super(Multi, self).reverse()
|
||||||
self.context.cfgimpl_get_values()._setvalue(self.opt, self)
|
self.context.cfgimpl_get_values()._setvalue(self.opt, self.path, self)
|
||||||
|
|
||||||
def insert(self, index, obj):
|
def insert(self, index, obj):
|
||||||
if self.opt.impl_get_multitype() in [multitypes.slave,
|
if self.opt.impl_get_multitype() in [multitypes.slave,
|
||||||
|
@ -424,7 +442,7 @@ class Multi(list):
|
||||||
raise SlaveError(_("cannot insert multi option {0} if master or "
|
raise SlaveError(_("cannot insert multi option {0} if master or "
|
||||||
"slave").format(self.opt._name))
|
"slave").format(self.opt._name))
|
||||||
super(Multi, self).insert(index, obj)
|
super(Multi, self).insert(index, obj)
|
||||||
self.context.cfgimpl_get_values()._setvalue(self.opt, self)
|
self.context.cfgimpl_get_values()._setvalue(self.opt, self.path, self)
|
||||||
|
|
||||||
def extend(self, iterable):
|
def extend(self, iterable):
|
||||||
if self.opt.impl_get_multitype() in [multitypes.slave,
|
if self.opt.impl_get_multitype() in [multitypes.slave,
|
||||||
|
@ -432,7 +450,7 @@ class Multi(list):
|
||||||
raise SlaveError(_("cannot extend multi option {0} if master or "
|
raise SlaveError(_("cannot extend multi option {0} if master or "
|
||||||
"slave").format(self.opt._name))
|
"slave").format(self.opt._name))
|
||||||
super(Multi, self).extend(iterable)
|
super(Multi, self).extend(iterable)
|
||||||
self.context.cfgimpl_get_values()._setvalue(self.opt, self)
|
self.context.cfgimpl_get_values()._setvalue(self.opt, self.path, self)
|
||||||
|
|
||||||
def _validate(self, value):
|
def _validate(self, value):
|
||||||
if value is not None:
|
if value is not None:
|
||||||
|
@ -465,5 +483,5 @@ class Multi(list):
|
||||||
).pop(key, force=True)
|
).pop(key, force=True)
|
||||||
#set value without valid properties
|
#set value without valid properties
|
||||||
ret = super(Multi, self).pop(key)
|
ret = super(Multi, self).pop(key)
|
||||||
self.context.cfgimpl_get_values()._setvalue(self.opt, self, validate_properties=not force)
|
self.context.cfgimpl_get_values()._setvalue(self.opt, self.path, self, validate_properties=not force)
|
||||||
return ret
|
return ret
|
||||||
|
|
Loading…
Reference in New Issue