add Calculation to properties
This commit is contained in:
parent
7c641961d3
commit
bb2ecc94d9
27 changed files with 2358 additions and 574 deletions
|
@ -5,12 +5,11 @@ from py.test import raises
|
||||||
from .autopath import do_autopath
|
from .autopath import do_autopath
|
||||||
do_autopath()
|
do_autopath()
|
||||||
|
|
||||||
from tiramisu.option import BoolOption, IPOption, IntOption, StrOption, OptionDescription, Leadership
|
from tiramisu import BoolOption, IPOption, IntOption, StrOption, OptionDescription, Leadership, Config, \
|
||||||
from tiramisu import Config
|
undefined, Calculation, Params, ParamValue, ParamOption, \
|
||||||
|
list_sessions, default_storage, delete_session, calc_value
|
||||||
from tiramisu.error import ConfigError, PropertiesOptionError
|
from tiramisu.error import ConfigError, PropertiesOptionError
|
||||||
from tiramisu.setting import groups
|
from tiramisu.setting import groups
|
||||||
from tiramisu import undefined, Params, ParamValue, ParamOption, \
|
|
||||||
list_sessions, default_storage, delete_session
|
|
||||||
|
|
||||||
|
|
||||||
def teardown_function(function):
|
def teardown_function(function):
|
||||||
|
@ -497,8 +496,12 @@ def test_cache_leader_callback():
|
||||||
|
|
||||||
def test_cache_requires():
|
def test_cache_requires():
|
||||||
a = BoolOption('activate_service', '', True)
|
a = BoolOption('activate_service', '', True)
|
||||||
b = IPOption('ip_address_service', '',
|
disabled_property = Calculation(calc_value,
|
||||||
requires=[{'option': a, 'expected': False, 'action': 'disabled'}])
|
Params(ParamValue('disabled'),
|
||||||
|
kwargs={'condition': ParamOption(a),
|
||||||
|
'expected': ParamValue(False),
|
||||||
|
'default': ParamValue(None)}))
|
||||||
|
b = IPOption('ip_address_service', '', properties=(disabled_property,))
|
||||||
od = OptionDescription('service', '', [a, b])
|
od = OptionDescription('service', '', [a, b])
|
||||||
cfg = Config(od)
|
cfg = Config(od)
|
||||||
cfg.property.read_write()
|
cfg.property.read_write()
|
||||||
|
@ -545,8 +548,12 @@ def test_cache_requires():
|
||||||
|
|
||||||
def test_cache_global_properties():
|
def test_cache_global_properties():
|
||||||
a = BoolOption('activate_service', '', True)
|
a = BoolOption('activate_service', '', True)
|
||||||
b = IPOption('ip_address_service', '',
|
disabled_property = Calculation(calc_value,
|
||||||
requires=[{'option': a, 'expected': False, 'action': 'disabled'}])
|
Params(ParamValue('disabled'),
|
||||||
|
kwargs={'condition': ParamOption(a),
|
||||||
|
'expected': ParamValue(False),
|
||||||
|
'default': ParamValue(None)}))
|
||||||
|
b = IPOption('ip_address_service', '', properties=(disabled_property,))
|
||||||
od = OptionDescription('service', '', [a, b])
|
od = OptionDescription('service', '', [a, b])
|
||||||
cfg = Config(od)
|
cfg = Config(od)
|
||||||
cfg.property.read_write()
|
cfg.property.read_write()
|
||||||
|
|
|
@ -131,7 +131,7 @@ def test_base_config_in_a_tree():
|
||||||
|
|
||||||
|
|
||||||
def test_not_valid_properties():
|
def test_not_valid_properties():
|
||||||
raises(TypeError, "stroption = StrOption('str', 'Test string option', default='abc', properties=['mandatory',])")
|
raises(AssertionError, "stroption = StrOption('str', 'Test string option', default='abc', properties='mandatory')")
|
||||||
|
|
||||||
|
|
||||||
def test_information_config():
|
def test_information_config():
|
||||||
|
|
|
@ -9,7 +9,7 @@ from tiramisu import BoolOption, StrOption, ChoiceOption, IPOption, \
|
||||||
UnicodeOption, PortOption, BroadcastOption, DomainnameOption, \
|
UnicodeOption, PortOption, BroadcastOption, DomainnameOption, \
|
||||||
EmailOption, URLOption, UsernameOption, FilenameOption, SymLinkOption, \
|
EmailOption, URLOption, UsernameOption, FilenameOption, SymLinkOption, \
|
||||||
OptionDescription, DynOptionDescription, SynDynOption, submulti, Leadership, \
|
OptionDescription, DynOptionDescription, SynDynOption, submulti, Leadership, \
|
||||||
Config, Params, ParamOption, ParamValue
|
Config, Params, ParamOption, ParamValue, Calculation, calc_value
|
||||||
from tiramisu.error import PropertiesOptionError, ConfigError, ConflictError
|
from tiramisu.error import PropertiesOptionError, ConfigError, ConflictError
|
||||||
from tiramisu.storage import list_sessions
|
from tiramisu.storage import list_sessions
|
||||||
|
|
||||||
|
@ -494,16 +494,24 @@ def test_decrease_dyndescription_context():
|
||||||
|
|
||||||
def test_dyndescription_root():
|
def test_dyndescription_root():
|
||||||
boolean = BoolOption('boolean', '', True)
|
boolean = BoolOption('boolean', '', True)
|
||||||
st1 = StrOption('st', '', requires=[{'option': boolean, 'expected': False,
|
disabled_property = Calculation(calc_value,
|
||||||
'action': 'disabled'}])
|
Params(ParamValue('disabled'),
|
||||||
|
kwargs={'condition': ParamOption(boolean),
|
||||||
|
'expected': ParamValue(False),
|
||||||
|
'default': ParamValue(None)}))
|
||||||
|
st1 = StrOption('st', '', properties=(disabled_property,))
|
||||||
dod = DynOptionDescription('dod', '', [boolean, st1], callback=return_list)
|
dod = DynOptionDescription('dod', '', [boolean, st1], callback=return_list)
|
||||||
raises(ConfigError, "Config(dod)")
|
raises(ConfigError, "Config(dod)")
|
||||||
|
|
||||||
|
|
||||||
def test_requires_dyndescription():
|
def test_requires_dyndescription():
|
||||||
boolean = BoolOption('boolean', '', True)
|
boolean = BoolOption('boolean', '', True)
|
||||||
st1 = StrOption('st', '', requires=[{'option': boolean, 'expected': False,
|
disabled_property = Calculation(calc_value,
|
||||||
'action': 'disabled'}])
|
Params(ParamValue('disabled'),
|
||||||
|
kwargs={'condition': ParamOption(boolean, raisepropertyerror=True),
|
||||||
|
'expected': ParamValue(False),
|
||||||
|
'default': ParamValue(None)}))
|
||||||
|
st1 = StrOption('st', '', properties=(disabled_property,))
|
||||||
dod = DynOptionDescription('dod', '', [st1], callback=return_list)
|
dod = DynOptionDescription('dod', '', [st1], callback=return_list)
|
||||||
od1 = OptionDescription('od', '', [dod])
|
od1 = OptionDescription('od', '', [dod])
|
||||||
od2 = OptionDescription('od', '', [od1, boolean])
|
od2 = OptionDescription('od', '', [od1, boolean])
|
||||||
|
@ -547,11 +555,18 @@ def test_requires_dyndescription():
|
||||||
|
|
||||||
def test_requires_dyndescription_boolean():
|
def test_requires_dyndescription_boolean():
|
||||||
boolean1 = BoolOption('boolean1', '', True)
|
boolean1 = BoolOption('boolean1', '', True)
|
||||||
boolean = BoolOption('boolean', '', True, requires=[{'option': boolean1,
|
disabled_property = Calculation(calc_value,
|
||||||
'expected': False,
|
Params(ParamValue('disabled'),
|
||||||
'action': 'disabled'}])
|
kwargs={'condition': ParamOption(boolean1, raisepropertyerror=True),
|
||||||
st = StrOption('st', '', requires=[{'option': boolean, 'expected': False,
|
'expected': ParamValue(False),
|
||||||
'action': 'disabled'}])
|
'default': ParamValue(None)}))
|
||||||
|
boolean = BoolOption('boolean', '', True, properties=(disabled_property,))
|
||||||
|
disabled_property = Calculation(calc_value,
|
||||||
|
Params(ParamValue('disabled'),
|
||||||
|
kwargs={'condition': ParamOption(boolean, raisepropertyerror=True),
|
||||||
|
'expected': ParamValue(False),
|
||||||
|
'default': ParamValue(None)}))
|
||||||
|
st = StrOption('st', '', properties=(disabled_property,))
|
||||||
dod = DynOptionDescription('dod', '', [st], callback=return_list)
|
dod = DynOptionDescription('dod', '', [st], callback=return_list)
|
||||||
od = OptionDescription('od', '', [dod])
|
od = OptionDescription('od', '', [dod])
|
||||||
od2 = OptionDescription('od', '', [od, boolean1, boolean])
|
od2 = OptionDescription('od', '', [od, boolean1, boolean])
|
||||||
|
@ -578,8 +593,12 @@ def test_requires_dyndescription_boolean():
|
||||||
|
|
||||||
def test_requires_dyndescription_in_dyn():
|
def test_requires_dyndescription_in_dyn():
|
||||||
boolean = BoolOption('boolean', '', True)
|
boolean = BoolOption('boolean', '', True)
|
||||||
st = StrOption('st', '', requires=[{'option': boolean, 'expected': False,
|
disabled_property = Calculation(calc_value,
|
||||||
'action': 'disabled'}])
|
Params(ParamValue('disabled'),
|
||||||
|
kwargs={'condition': ParamOption(boolean, raisepropertyerror=True),
|
||||||
|
'expected': ParamValue(False),
|
||||||
|
'default': ParamValue(None)}))
|
||||||
|
st = StrOption('st', '', properties=(disabled_property,))
|
||||||
dod = DynOptionDescription('dod', '', [boolean, st], callback=return_list)
|
dod = DynOptionDescription('dod', '', [boolean, st], callback=return_list)
|
||||||
od = OptionDescription('od', '', [dod])
|
od = OptionDescription('od', '', [dod])
|
||||||
od2 = OptionDescription('od', '', [od])
|
od2 = OptionDescription('od', '', [od])
|
||||||
|
@ -608,9 +627,12 @@ def test_requires_dyndescription_in_dyn():
|
||||||
def test_requires_dyndescription2():
|
def test_requires_dyndescription2():
|
||||||
boolean = BoolOption('boolean', '', True)
|
boolean = BoolOption('boolean', '', True)
|
||||||
st1 = StrOption('st', '')
|
st1 = StrOption('st', '')
|
||||||
dod = DynOptionDescription('dod', '', [st1], callback=return_list,
|
disabled_property = Calculation(calc_value,
|
||||||
requires=[{'option': boolean, 'expected': False,
|
Params(ParamValue('disabled'),
|
||||||
'action': 'disabled'}])
|
kwargs={'condition': ParamOption(boolean, raisepropertyerror=True),
|
||||||
|
'expected': ParamValue(False),
|
||||||
|
'default': ParamValue(None)}))
|
||||||
|
dod = DynOptionDescription('dod', '', [st1], callback=return_list, properties=(disabled_property,))
|
||||||
od1 = OptionDescription('od', '', [dod])
|
od1 = OptionDescription('od', '', [dod])
|
||||||
od2 = OptionDescription('od', '', [od1, boolean])
|
od2 = OptionDescription('od', '', [od1, boolean])
|
||||||
api = Config(od2)
|
api = Config(od2)
|
||||||
|
|
|
@ -8,7 +8,7 @@ from py.test import raises
|
||||||
from tiramisu.setting import owners, groups
|
from tiramisu.setting import owners, groups
|
||||||
from tiramisu import ChoiceOption, BoolOption, IntOption, FloatOption, \
|
from tiramisu import ChoiceOption, BoolOption, IntOption, FloatOption, \
|
||||||
StrOption, OptionDescription, SymLinkOption, Leadership, Config, \
|
StrOption, OptionDescription, SymLinkOption, Leadership, Config, \
|
||||||
Params, ParamContext, ParamOption, ParamValue
|
Calculation, Params, ParamContext, ParamOption, ParamValue, calc_value
|
||||||
from tiramisu.error import PropertiesOptionError, ConfigError
|
from tiramisu.error import PropertiesOptionError, ConfigError
|
||||||
from tiramisu.storage import list_sessions
|
from tiramisu.storage import list_sessions
|
||||||
|
|
||||||
|
@ -41,14 +41,23 @@ def make_description_freeze():
|
||||||
floatoption = FloatOption('float', 'Test float option', default=2.3)
|
floatoption = FloatOption('float', 'Test float option', default=2.3)
|
||||||
stroption = StrOption('str', 'Test string option', default="abc")
|
stroption = StrOption('str', 'Test string option', default="abc")
|
||||||
boolop = BoolOption('boolop', 'Test boolean option op', default=[True], multi=True)
|
boolop = BoolOption('boolop', 'Test boolean option op', default=[True], multi=True)
|
||||||
wantref_option = BoolOption('wantref', 'Test requires', default=False, properties=('force_store_value',),
|
hidden_property = Calculation(calc_value,
|
||||||
requires=({'option': booloption, 'expected': True, 'action': 'hidden'},))
|
Params(ParamValue('hidden'),
|
||||||
|
kwargs={'condition': ParamOption(booloption, raisepropertyerror=True),
|
||||||
|
'expected': ParamValue(True),
|
||||||
|
'default': ParamValue(None)}))
|
||||||
|
wantref_option = BoolOption('wantref', 'Test requires', default=False, properties=('force_store_value', hidden_property))
|
||||||
wantref2_option = BoolOption('wantref2', 'Test requires', default=False, properties=('force_store_value', 'hidden'))
|
wantref2_option = BoolOption('wantref2', 'Test requires', default=False, properties=('force_store_value', 'hidden'))
|
||||||
wantref3_option = BoolOption('wantref3', 'Test requires', default=[False], multi=True, properties=('force_store_value',))
|
wantref3_option = BoolOption('wantref3', 'Test requires', default=[False], multi=True, properties=('force_store_value',))
|
||||||
st2 = SymLinkOption('st2', wantref3_option)
|
st2 = SymLinkOption('st2', wantref3_option)
|
||||||
|
hidden_property = Calculation(calc_value,
|
||||||
|
Params(ParamValue('hidden'),
|
||||||
|
kwargs={'condition': ParamOption(booloption, raisepropertyerror=True),
|
||||||
|
'expected': ParamValue(True),
|
||||||
|
'default': ParamValue(None)}))
|
||||||
wantframework_option = BoolOption('wantframework', 'Test requires',
|
wantframework_option = BoolOption('wantframework', 'Test requires',
|
||||||
default=False,
|
default=False,
|
||||||
requires=({'option': booloption, 'expected': True, 'action': 'hidden'},))
|
properties=(hidden_property,))
|
||||||
|
|
||||||
gcgroup = OptionDescription('gc', '', [gcoption, gcdummy, floatoption])
|
gcgroup = OptionDescription('gc', '', [gcoption, gcdummy, floatoption])
|
||||||
descr = OptionDescription('tiramisu', '', [gcgroup, booloption, objspaceoption,
|
descr = OptionDescription('tiramisu', '', [gcgroup, booloption, objspaceoption,
|
||||||
|
|
|
@ -6,7 +6,8 @@ do_autopath()
|
||||||
from py.test import raises
|
from py.test import raises
|
||||||
from tiramisu import Config
|
from tiramisu import Config
|
||||||
from tiramisu import IntOption, StrOption, UnicodeOption, OptionDescription, \
|
from tiramisu import IntOption, StrOption, UnicodeOption, OptionDescription, \
|
||||||
SymLinkOption, Leadership, undefined, Params, ParamOption
|
SymLinkOption, Leadership, undefined, Calculation, Params, \
|
||||||
|
ParamOption, ParamValue, calc_value
|
||||||
from tiramisu.error import PropertiesOptionError, ConfigError
|
from tiramisu.error import PropertiesOptionError, ConfigError
|
||||||
from tiramisu.setting import groups
|
from tiramisu.setting import groups
|
||||||
from tiramisu.storage import list_sessions
|
from tiramisu.storage import list_sessions
|
||||||
|
@ -575,7 +576,12 @@ def test_mandatory_warnings_requires():
|
||||||
properties=('mandatory', ))
|
properties=('mandatory', ))
|
||||||
stroption2 = UnicodeOption('unicode2', 'Test string option',
|
stroption2 = UnicodeOption('unicode2', 'Test string option',
|
||||||
properties=('mandatory', ))
|
properties=('mandatory', ))
|
||||||
stroption3 = StrOption('str3', 'Test string option', multi=True, requires=[{'option': stroption, 'expected': 'yes', 'action': 'mandatory', 'transitive': False}])
|
mandatory_property = Calculation(calc_value,
|
||||||
|
Params(ParamValue('mandatory'),
|
||||||
|
kwargs={'condition': ParamOption(stroption, notraisepropertyerror=True),
|
||||||
|
'expected': ParamValue('yes'),
|
||||||
|
'no_condition_is_invalid': ParamValue(True)}))
|
||||||
|
stroption3 = StrOption('str3', 'Test string option', multi=True, properties=(mandatory_property,))
|
||||||
descr = OptionDescription('tiram', '', [stroption, stroption1, stroption2, stroption3])
|
descr = OptionDescription('tiram', '', [stroption, stroption1, stroption2, stroption3])
|
||||||
cfg = Config(descr)
|
cfg = Config(descr)
|
||||||
cfg.option('str').value.set('')
|
cfg.option('str').value.set('')
|
||||||
|
@ -593,7 +599,13 @@ def test_mandatory_warnings_requires_leadership():
|
||||||
stroption = StrOption('str', 'Test string option', default="abc",
|
stroption = StrOption('str', 'Test string option', default="abc",
|
||||||
properties=('mandatory', ))
|
properties=('mandatory', ))
|
||||||
stroption1 = StrOption('str1', 'Test string option', multi=True)
|
stroption1 = StrOption('str1', 'Test string option', multi=True)
|
||||||
stroption2 = StrOption('str2', 'Test string option', multi=True, requires=[{'option': stroption, 'expected': 'yes', 'action': 'mandatory', 'transitive': False}])
|
mandatory_property = Calculation(calc_value,
|
||||||
|
Params(ParamValue(None),
|
||||||
|
kwargs={'condition': ParamOption(stroption),
|
||||||
|
'expected': ParamValue('yes'),
|
||||||
|
'inverse_condition': ParamValue(True),
|
||||||
|
'default': ParamValue('mandatory')}))
|
||||||
|
stroption2 = StrOption('str2', 'Test string option', multi=True, properties=(mandatory_property,))
|
||||||
leadership = Leadership('leader', 'leadership', [stroption1, stroption2])
|
leadership = Leadership('leader', 'leadership', [stroption1, stroption2])
|
||||||
descr = OptionDescription('tiram', '', [stroption, leadership])
|
descr = OptionDescription('tiram', '', [stroption, leadership])
|
||||||
cfg = Config(descr)
|
cfg = Config(descr)
|
||||||
|
@ -607,7 +619,13 @@ def test_mandatory_warnings_requires_leadership():
|
||||||
def test_mandatory_warnings_requires_leadership_follower():
|
def test_mandatory_warnings_requires_leadership_follower():
|
||||||
stroption = StrOption('str', 'Test string option', multi=True)
|
stroption = StrOption('str', 'Test string option', multi=True)
|
||||||
stroption1 = StrOption('str1', 'Test string option', multi=True)
|
stroption1 = StrOption('str1', 'Test string option', multi=True)
|
||||||
stroption2 = StrOption('str2', 'Test string option', multi=True, requires=[{'option': stroption1, 'expected': 'yes', 'action': 'mandatory', 'transitive': False}])
|
mandatory_property = Calculation(calc_value,
|
||||||
|
Params(ParamValue(None),
|
||||||
|
kwargs={'condition': ParamOption(stroption1),
|
||||||
|
'expected': ParamValue('yes'),
|
||||||
|
'inverse_condition': ParamValue(True),
|
||||||
|
'default': ParamValue('mandatory')}))
|
||||||
|
stroption2 = StrOption('str2', 'Test string option', multi=True, properties=(mandatory_property,))
|
||||||
leadership = Leadership('leader', 'leadership', [stroption, stroption1, stroption2])
|
leadership = Leadership('leader', 'leadership', [stroption, stroption1, stroption2])
|
||||||
descr = OptionDescription('tiram', '', [leadership])
|
descr = OptionDescription('tiram', '', [leadership])
|
||||||
cfg = Config(descr)
|
cfg = Config(descr)
|
||||||
|
|
|
@ -5,7 +5,7 @@ do_autopath()
|
||||||
from tiramisu.setting import groups, owners
|
from tiramisu.setting import groups, owners
|
||||||
from tiramisu import IntOption, StrOption, NetworkOption, NetmaskOption, BoolOption, ChoiceOption, \
|
from tiramisu import IntOption, StrOption, NetworkOption, NetmaskOption, BoolOption, ChoiceOption, \
|
||||||
IPOption, OptionDescription, Leadership, Config, GroupConfig, MetaConfig, \
|
IPOption, OptionDescription, Leadership, Config, GroupConfig, MetaConfig, \
|
||||||
Params, ParamOption, ParamValue
|
Calculation, Params, ParamOption, ParamValue, calc_value
|
||||||
from tiramisu.error import ConfigError, ConflictError, PropertiesOptionError, LeadershipError, APIError
|
from tiramisu.error import ConfigError, ConflictError, PropertiesOptionError, LeadershipError, APIError
|
||||||
from tiramisu.storage import list_sessions
|
from tiramisu.storage import list_sessions
|
||||||
from .config import config_type, get_config
|
from .config import config_type, get_config
|
||||||
|
@ -748,7 +748,11 @@ def test_meta_exception_meta():
|
||||||
def test_meta_properties_requires1():
|
def test_meta_properties_requires1():
|
||||||
opt1 = BoolOption('opt1', 'opt1', False)
|
opt1 = BoolOption('opt1', 'opt1', False)
|
||||||
opt2 = BoolOption('opt2', "")
|
opt2 = BoolOption('opt2', "")
|
||||||
od2 = OptionDescription('od2', "", [opt2], requires=({'option': opt1, 'expected': False, 'action': 'disabled'},))
|
disabled_property = Calculation(calc_value,
|
||||||
|
Params(ParamValue('disabled'),
|
||||||
|
kwargs={'condition': ParamOption(opt1, todict=True),
|
||||||
|
'expected': ParamValue(False)}))
|
||||||
|
od2 = OptionDescription('od2', "", [opt2], properties=(disabled_property,))
|
||||||
opt3 = BoolOption('opt3', '')
|
opt3 = BoolOption('opt3', '')
|
||||||
opt2.impl_add_consistency('not_equal', opt3)
|
opt2.impl_add_consistency('not_equal', opt3)
|
||||||
od = OptionDescription('root', '', [opt1, od2, opt3])
|
od = OptionDescription('root', '', [opt1, od2, opt3])
|
||||||
|
@ -765,7 +769,12 @@ def test_meta_properties_requires_mandatory():
|
||||||
probes = BoolOption('probes', 'probes available', False)
|
probes = BoolOption('probes', 'probes available', False)
|
||||||
eth0_method = ChoiceOption('eth0_method', '', ('static', 'dhcp'), 'static')
|
eth0_method = ChoiceOption('eth0_method', '', ('static', 'dhcp'), 'static')
|
||||||
ip_address = IPOption('ip_address', '')
|
ip_address = IPOption('ip_address', '')
|
||||||
ip_eth0 = IPOption('ip_eth0', "ip", requires=({'option': probes, 'expected': True, 'action': 'mandatory'},), callback=return_condition, callback_params=Params(kwargs={'val': ParamOption(ip_address), 'condition': ParamOption(eth0_method), 'expected': ParamValue('dhcp')}))
|
mandatory_property = Calculation(calc_value,
|
||||||
|
Params(ParamValue('mandatory'),
|
||||||
|
kwargs={'condition': ParamOption(probes),
|
||||||
|
'expected': ParamValue('yes'),
|
||||||
|
'default': ParamValue(None)}))
|
||||||
|
ip_eth0 = IPOption('ip_eth0', "ip", properties=(mandatory_property,), callback=return_condition, callback_params=Params(kwargs={'val': ParamOption(ip_address), 'condition': ParamOption(eth0_method), 'expected': ParamValue('dhcp')}))
|
||||||
ip_gw = IPOption('ip_gw', 'gw')
|
ip_gw = IPOption('ip_gw', 'gw')
|
||||||
ip_gw.impl_add_consistency('not_equal', ip_eth0)
|
ip_gw.impl_add_consistency('not_equal', ip_eth0)
|
||||||
od = OptionDescription('root', '', [ip_gw, probes, eth0_method, ip_address, ip_eth0])
|
od = OptionDescription('root', '', [ip_gw, probes, eth0_method, ip_address, ip_eth0])
|
||||||
|
|
|
@ -3,13 +3,14 @@ do_autopath()
|
||||||
from .config import config_type, get_config
|
from .config import config_type, get_config
|
||||||
|
|
||||||
from py.test import raises
|
from py.test import raises
|
||||||
|
import warnings
|
||||||
|
|
||||||
from tiramisu import Config
|
from tiramisu import Config
|
||||||
from tiramisu.config import KernelConfig
|
from tiramisu.config import KernelConfig
|
||||||
from tiramisu.setting import groups, owners
|
from tiramisu.setting import groups, owners
|
||||||
from tiramisu import ChoiceOption, BoolOption, IntOption, FloatOption, \
|
from tiramisu import ChoiceOption, BoolOption, IntOption, FloatOption, \
|
||||||
StrOption, OptionDescription, SymLinkOption, IPOption, NetmaskOption, Leadership, \
|
StrOption, OptionDescription, SymLinkOption, IPOption, NetmaskOption, Leadership, \
|
||||||
undefined, Params, ParamOption, ParamValue, ParamContext, calc_value
|
undefined, Calculation, Params, ParamOption, ParamValue, ParamContext, calc_value
|
||||||
from tiramisu.error import PropertiesOptionError, ConflictError, LeadershipError, ConfigError
|
from tiramisu.error import PropertiesOptionError, ConflictError, LeadershipError, ConfigError
|
||||||
from tiramisu.i18n import _
|
from tiramisu.i18n import _
|
||||||
from tiramisu.storage import list_sessions
|
from tiramisu.storage import list_sessions
|
||||||
|
@ -102,11 +103,9 @@ def make_description_duplicates():
|
||||||
floatoption = FloatOption('float', 'Test float option', default=2.3)
|
floatoption = FloatOption('float', 'Test float option', default=2.3)
|
||||||
stroption = StrOption('str', 'Test string option', default="abc")
|
stroption = StrOption('str', 'Test string option', default="abc")
|
||||||
boolop = BoolOption('boolop', 'Test boolean option op', default=True)
|
boolop = BoolOption('boolop', 'Test boolean option op', default=True)
|
||||||
wantref_option = BoolOption('wantref', 'Test requires', default=False,
|
wantref_option = BoolOption('wantref', 'Test requires', default=False)
|
||||||
requires=({'option': boolop, 'expected': True, 'action': 'hidden'},))
|
|
||||||
wantframework_option = BoolOption('wantframework', 'Test requires',
|
wantframework_option = BoolOption('wantframework', 'Test requires',
|
||||||
default=False,
|
default=False)
|
||||||
requires=({'option': boolop, 'expected': True, 'action': 'hidden'},))
|
|
||||||
# dummy2 (same path)
|
# dummy2 (same path)
|
||||||
gcdummy2 = BoolOption('dummy', 'dummy2', default=True)
|
gcdummy2 = BoolOption('dummy', 'dummy2', default=True)
|
||||||
# dummy3 (same name)
|
# dummy3 (same name)
|
||||||
|
@ -123,13 +122,18 @@ def test_identical_paths():
|
||||||
"""If in the schema (the option description) there is something that
|
"""If in the schema (the option description) there is something that
|
||||||
have the same name, an exection is raised
|
have the same name, an exection is raised
|
||||||
"""
|
"""
|
||||||
raises(ConflictError, "make_description_duplicates()")
|
with warnings.catch_warnings(record=True) as w:
|
||||||
|
raises(ConflictError, "make_description_duplicates()")
|
||||||
|
|
||||||
|
|
||||||
def test_hidden_if_in2(config_type):
|
def test_hidden_if_in2(config_type):
|
||||||
intoption = IntOption('int', 'Test int option', default=0)
|
intoption = IntOption('int', 'Test int option', default=0)
|
||||||
stroption = StrOption('str', 'Test string option', default="abc",
|
hidden_property = Calculation(calc_value,
|
||||||
requires=({'option': intoption, 'expected': 1, 'action': 'hidden'},))
|
Params(ParamValue('hidden'),
|
||||||
|
kwargs={'condition': ParamOption(intoption),
|
||||||
|
'expected': ParamValue(1),
|
||||||
|
'default': ParamValue(None)}))
|
||||||
|
stroption = StrOption('str', 'Test string option', default="abc", properties=(hidden_property,))
|
||||||
descr = OptionDescription('constraints', '', [stroption, intoption])
|
descr = OptionDescription('constraints', '', [stroption, intoption])
|
||||||
cfg_ori = Config(descr)
|
cfg_ori = Config(descr)
|
||||||
cfg_ori.property.read_write()
|
cfg_ori.property.read_write()
|
||||||
|
@ -154,8 +158,12 @@ def test_hidden_if_in_with_group(config_type):
|
||||||
booloption = BoolOption('bool', 'Test boolean option', default=True)
|
booloption = BoolOption('bool', 'Test boolean option', default=True)
|
||||||
intoption = IntOption('int', 'Test int option', default=0)
|
intoption = IntOption('int', 'Test int option', default=0)
|
||||||
stroption = StrOption('str', 'Test string option', default="abc")
|
stroption = StrOption('str', 'Test string option', default="abc")
|
||||||
gcgroup = OptionDescription('gc', '', [gcoption, gcdummy, floatoption],
|
hidden_property = Calculation(calc_value,
|
||||||
requires=({'option': intoption, 'expected': 1, 'action': 'hidden'},))
|
Params(ParamValue('hidden'),
|
||||||
|
kwargs={'condition': ParamOption(intoption),
|
||||||
|
'expected': ParamValue(1),
|
||||||
|
'default': ParamValue(None)}))
|
||||||
|
gcgroup = OptionDescription('gc', '', [gcoption, gcdummy, floatoption], properties=(hidden_property,))
|
||||||
descr = OptionDescription('constraints', '', [gcgroup, booloption,
|
descr = OptionDescription('constraints', '', [gcgroup, booloption,
|
||||||
objspaceoption, stroption, intoption])
|
objspaceoption, stroption, intoption])
|
||||||
cfg_ori = Config(descr)
|
cfg_ori = Config(descr)
|
||||||
|
@ -179,8 +187,12 @@ def test_disabled_with_group():
|
||||||
booloption = BoolOption('bool', 'Test boolean option', default=True)
|
booloption = BoolOption('bool', 'Test boolean option', default=True)
|
||||||
intoption = IntOption('int', 'Test int option', default=0)
|
intoption = IntOption('int', 'Test int option', default=0)
|
||||||
stroption = StrOption('str', 'Test string option', default="abc")
|
stroption = StrOption('str', 'Test string option', default="abc")
|
||||||
gcgroup = OptionDescription('gc', '', [gcoption, gcdummy, floatoption],
|
disabled_property = Calculation(calc_value,
|
||||||
requires=({'option': intoption, 'expected': 1, 'action': 'disabled'},))
|
Params(ParamValue('disabled'),
|
||||||
|
kwargs={'condition': ParamOption(intoption),
|
||||||
|
'expected': ParamValue(1),
|
||||||
|
'default': ParamValue(None)}))
|
||||||
|
gcgroup = OptionDescription('gc', '', [gcoption, gcdummy, floatoption], properties=(disabled_property,))
|
||||||
descr = OptionDescription('constraints', '', [gcgroup, booloption,
|
descr = OptionDescription('constraints', '', [gcgroup, booloption,
|
||||||
objspaceoption, stroption, intoption])
|
objspaceoption, stroption, intoption])
|
||||||
cfg = Config(descr)
|
cfg = Config(descr)
|
||||||
|
@ -201,11 +213,15 @@ def make_description_callback():
|
||||||
floatoption = FloatOption('float', 'Test float option', default=2.3)
|
floatoption = FloatOption('float', 'Test float option', default=2.3)
|
||||||
stroption = StrOption('str', 'Test string option', default="abc")
|
stroption = StrOption('str', 'Test string option', default="abc")
|
||||||
boolop = BoolOption('boolop', 'Test boolean option op', default=True)
|
boolop = BoolOption('boolop', 'Test boolean option op', default=True)
|
||||||
wantref_option = BoolOption('wantref', 'Test requires', default=False,
|
hidden_property = Calculation(calc_value,
|
||||||
requires=({'option': boolop, 'expected': True, 'action': 'hidden'},))
|
Params(ParamValue('hidden'),
|
||||||
|
kwargs={'condition': ParamOption(boolop),
|
||||||
|
'expected': ParamValue(True),
|
||||||
|
'default': ParamValue(None)}))
|
||||||
|
wantref_option = BoolOption('wantref', 'Test requires', default=False, properties=(hidden_property,))
|
||||||
wantframework_option = BoolOption('wantframework', 'Test requires',
|
wantframework_option = BoolOption('wantframework', 'Test requires',
|
||||||
default=False,
|
default=False,
|
||||||
requires=({'option': boolop, 'expected': True, 'action': 'hidden'},))
|
properties=(hidden_property,))
|
||||||
gcgroup = OptionDescription('gc', '', [gcoption, gcdummy, floatoption])
|
gcgroup = OptionDescription('gc', '', [gcoption, gcdummy, floatoption])
|
||||||
descr = OptionDescription('constraints', '', [gcgroup, booloption, objspaceoption,
|
descr = OptionDescription('constraints', '', [gcgroup, booloption, objspaceoption,
|
||||||
wantref_option, stroption,
|
wantref_option, stroption,
|
||||||
|
@ -268,7 +284,7 @@ def test_params():
|
||||||
def test_param_option():
|
def test_param_option():
|
||||||
val1 = StrOption('val1', "")
|
val1 = StrOption('val1', "")
|
||||||
raises(ValueError, "ParamOption('str')")
|
raises(ValueError, "ParamOption('str')")
|
||||||
raises(ValueError, "ParamOption(val1, 'str')")
|
raises(AssertionError, "ParamOption(val1, 'str')")
|
||||||
|
|
||||||
|
|
||||||
def test_callback_invalid():
|
def test_callback_invalid():
|
||||||
|
|
|
@ -9,7 +9,8 @@ from tiramisu.i18n import _
|
||||||
from tiramisu.error import display_list, ConfigError
|
from tiramisu.error import display_list, ConfigError
|
||||||
from tiramisu.setting import owners, groups
|
from tiramisu.setting import owners, groups
|
||||||
from tiramisu import ChoiceOption, BoolOption, IntOption, FloatOption, \
|
from tiramisu import ChoiceOption, BoolOption, IntOption, FloatOption, \
|
||||||
StrOption, OptionDescription, Leadership, Config, undefined
|
StrOption, OptionDescription, Leadership, Config, undefined, \
|
||||||
|
Calculation, Params, ParamOption, ParamValue, ParamIndex, calc_value, calc_value_property_help
|
||||||
from tiramisu.error import PropertiesOptionError
|
from tiramisu.error import PropertiesOptionError
|
||||||
from tiramisu.storage import list_sessions
|
from tiramisu.storage import list_sessions
|
||||||
|
|
||||||
|
@ -168,8 +169,11 @@ def test_reset_with_multi(config_type):
|
||||||
def test_property_only_raises():
|
def test_property_only_raises():
|
||||||
s = StrOption("string", "", default=["string"], default_multi="string", multi=True)
|
s = StrOption("string", "", default=["string"], default_multi="string", multi=True)
|
||||||
intoption = IntOption('int', 'Test int option', default=0)
|
intoption = IntOption('int', 'Test int option', default=0)
|
||||||
stroption = StrOption('str', 'Test string option', default=["abc"], default_multi="abc",
|
hidden_property = Calculation(calc_value,
|
||||||
requires=[{'option': intoption, 'expected': 1, 'action': 'hidden'}], multi=True)
|
Params(ParamValue('hidden'),
|
||||||
|
kwargs={'condition': ParamOption(intoption),
|
||||||
|
'expected': ParamValue(1)}))
|
||||||
|
stroption = StrOption('str', 'Test string option', default=["abc"], default_multi="abc", properties=(hidden_property,), multi=True)
|
||||||
descr = OptionDescription("options", "", [s, intoption, stroption])
|
descr = OptionDescription("options", "", [s, intoption, stroption])
|
||||||
cfg = Config(descr)
|
cfg = Config(descr)
|
||||||
cfg.property.read_write()
|
cfg.property.read_write()
|
||||||
|
@ -231,8 +235,11 @@ def test_access_with_multi_default(config_type):
|
||||||
def test_multi_with_requires():
|
def test_multi_with_requires():
|
||||||
s = StrOption("string", "", default=["string"], default_multi="string", multi=True)
|
s = StrOption("string", "", default=["string"], default_multi="string", multi=True)
|
||||||
intoption = IntOption('int', 'Test int option', default=0)
|
intoption = IntOption('int', 'Test int option', default=0)
|
||||||
stroption = StrOption('str', 'Test string option', default=["abc"], default_multi="abc",
|
hidden_property = Calculation(calc_value,
|
||||||
requires=[{'option': intoption, 'expected': 1, 'action': 'hidden'}], multi=True)
|
Params(ParamValue('hidden'),
|
||||||
|
kwargs={'condition': ParamOption(intoption),
|
||||||
|
'expected': ParamValue(1)}))
|
||||||
|
stroption = StrOption('str', 'Test string option', default=["abc"], default_multi="abc", properties=(hidden_property,), multi=True)
|
||||||
descr = OptionDescription("options", "", [s, intoption, stroption])
|
descr = OptionDescription("options", "", [s, intoption, stroption])
|
||||||
cfg = Config(descr)
|
cfg = Config(descr)
|
||||||
cfg.property.read_write()
|
cfg.property.read_write()
|
||||||
|
@ -242,23 +249,32 @@ def test_multi_with_requires():
|
||||||
assert 'hidden' in cfg.forcepermissive.option('str').property.get()
|
assert 'hidden' in cfg.forcepermissive.option('str').property.get()
|
||||||
|
|
||||||
|
|
||||||
def test__requires_with_inverted():
|
def test_requires_with_inverted():
|
||||||
s = StrOption("string", "", default=["string"], multi=True)
|
s = StrOption("string", "", default=["string"], multi=True)
|
||||||
intoption = IntOption('int', 'Test int option', default=0)
|
intoption = IntOption('int', 'Test int option', default=0)
|
||||||
stroption = StrOption('str', 'Test string option', default=["abc"], default_multi="abc",
|
hide_property = Calculation(calc_value,
|
||||||
requires=[{'option': intoption, 'expected': 1, 'action': 'hide', 'inverse': True}], multi=True)
|
Params(ParamValue('hide'),
|
||||||
|
kwargs={'condition': ParamOption(intoption),
|
||||||
|
'expected': ParamValue(1),
|
||||||
|
'inverse_condition': ParamValue(True)}))
|
||||||
|
stroption = StrOption('str', 'Test string option', default=["abc"], default_multi="abc", properties=(hide_property,), multi=True)
|
||||||
descr = OptionDescription("options", "", [s, intoption, stroption])
|
descr = OptionDescription("options", "", [s, intoption, stroption])
|
||||||
cfg = Config(descr)
|
cfg = Config(descr)
|
||||||
assert not 'hidden' in cfg.option('str').property.get()
|
assert not 'hidden' in cfg.option('str').property.get()
|
||||||
|
assert 'hide' in cfg.option('str').property.get()
|
||||||
cfg.option('int').value.set(1)
|
cfg.option('int').value.set(1)
|
||||||
assert not 'hidden' in cfg.option('str').property.get()
|
assert not 'hidden' in cfg.option('str').property.get()
|
||||||
|
assert not 'hide' in cfg.option('str').property.get()
|
||||||
|
|
||||||
|
|
||||||
def test_multi_with_requires_in_another_group():
|
def test_multi_with_requires_in_another_group():
|
||||||
s = StrOption("string", "", default=["string"], multi=True)
|
s = StrOption("string", "", default=["string"], multi=True)
|
||||||
intoption = IntOption('int', 'Test int option', default=0)
|
intoption = IntOption('int', 'Test int option', default=0)
|
||||||
stroption = StrOption('str', 'Test string option', default=["abc"],
|
hidden_property = Calculation(calc_value,
|
||||||
requires=[{'option': intoption, 'expected': 1, 'action': 'hidden'}], multi=True)
|
Params(ParamValue('hidden'),
|
||||||
|
kwargs={'condition': ParamOption(intoption),
|
||||||
|
'expected': ParamValue(1)}))
|
||||||
|
stroption = StrOption('str', 'Test string option', default=["abc"], properties=(hidden_property,), multi=True)
|
||||||
descr = OptionDescription("opt", "", [stroption])
|
descr = OptionDescription("opt", "", [stroption])
|
||||||
descr2 = OptionDescription("opt2", "", [intoption, s, descr])
|
descr2 = OptionDescription("opt2", "", [intoption, s, descr])
|
||||||
cfg = Config(descr2)
|
cfg = Config(descr2)
|
||||||
|
@ -272,8 +288,12 @@ def test_multi_with_requires_in_another_group():
|
||||||
def test_multi_with_requires_in_another_group_inverse():
|
def test_multi_with_requires_in_another_group_inverse():
|
||||||
s = StrOption("string", "", default=["string"], multi=True)
|
s = StrOption("string", "", default=["string"], multi=True)
|
||||||
intoption = IntOption('int', 'Test int option', default=0)
|
intoption = IntOption('int', 'Test int option', default=0)
|
||||||
stroption = StrOption('str', 'Test string option', default=["abc"],
|
hidden_property = Calculation(calc_value,
|
||||||
requires=[{'option': intoption, 'expected': 0, 'action': 'hidden', 'inverse': True}], multi=True)
|
Params(ParamValue('hidden'),
|
||||||
|
kwargs={'condition': ParamOption(intoption),
|
||||||
|
'expected': ParamValue(1)}))
|
||||||
|
# requires=[{'option': intoption, 'expected': 1, 'action': 'hidden'}], multi=True)
|
||||||
|
stroption = StrOption('str', 'Test string option', default=["abc"], properties=(hidden_property,), multi=True)
|
||||||
descr = OptionDescription("opt", "", [stroption])
|
descr = OptionDescription("opt", "", [stroption])
|
||||||
descr2 = OptionDescription("opt2", "", [intoption, s, descr])
|
descr2 = OptionDescription("opt2", "", [intoption, s, descr])
|
||||||
cfg = Config(descr2)
|
cfg = Config(descr2)
|
||||||
|
@ -287,8 +307,11 @@ def test_multi_with_requires_in_another_group_inverse():
|
||||||
def test_apply_requires_from_config():
|
def test_apply_requires_from_config():
|
||||||
s = StrOption("string", "", default=["string"], multi=True)
|
s = StrOption("string", "", default=["string"], multi=True)
|
||||||
intoption = IntOption('int', 'Test int option', default=0)
|
intoption = IntOption('int', 'Test int option', default=0)
|
||||||
stroption = StrOption('str', 'Test string option', default=["abc"],
|
hidden_property = Calculation(calc_value,
|
||||||
requires=[{'option': intoption, 'expected': 1, 'action': 'hidden'}], multi=True)
|
Params(ParamValue('hidden'),
|
||||||
|
kwargs={'condition': ParamOption(intoption),
|
||||||
|
'expected': ParamValue(1)}))
|
||||||
|
stroption = StrOption('str', 'Test string option', default=["abc"], properties=(hidden_property,), multi=True)
|
||||||
descr = OptionDescription("opt", "", [stroption])
|
descr = OptionDescription("opt", "", [stroption])
|
||||||
descr2 = OptionDescription("opt2", "", [intoption, s, descr])
|
descr2 = OptionDescription("opt2", "", [intoption, s, descr])
|
||||||
cfg = Config(descr2)
|
cfg = Config(descr2)
|
||||||
|
@ -304,8 +327,11 @@ def test_apply_requires_from_config():
|
||||||
def test_apply_requires_with_disabled():
|
def test_apply_requires_with_disabled():
|
||||||
s = StrOption("string", "", default=["string"], multi=True)
|
s = StrOption("string", "", default=["string"], multi=True)
|
||||||
intoption = IntOption('int', 'Test int option', default=0)
|
intoption = IntOption('int', 'Test int option', default=0)
|
||||||
stroption = StrOption('str', 'Test string option', default=["abc"],
|
disabled_property = Calculation(calc_value,
|
||||||
requires=[{'option': intoption, 'expected': 1, 'action': 'disabled'}], multi=True)
|
Params(ParamValue('disabled'),
|
||||||
|
kwargs={'condition': ParamOption(intoption),
|
||||||
|
'expected': ParamValue(1)}))
|
||||||
|
stroption = StrOption('str', 'Test string option', default=["abc"], properties=(disabled_property,), multi=True)
|
||||||
descr = OptionDescription("opt", "", [stroption])
|
descr = OptionDescription("opt", "", [stroption])
|
||||||
descr2 = OptionDescription("opt2", "", [intoption, s, descr])
|
descr2 = OptionDescription("opt2", "", [intoption, s, descr])
|
||||||
cfg = Config(descr2)
|
cfg = Config(descr2)
|
||||||
|
@ -321,8 +347,11 @@ def test_apply_requires_with_disabled():
|
||||||
def test_multi_with_requires_with_disabled_in_another_group():
|
def test_multi_with_requires_with_disabled_in_another_group():
|
||||||
s = StrOption("string", "", default=["string"], multi=True)
|
s = StrOption("string", "", default=["string"], multi=True)
|
||||||
intoption = IntOption('int', 'Test int option', default=0)
|
intoption = IntOption('int', 'Test int option', default=0)
|
||||||
stroption = StrOption('str', 'Test string option', default=["abc"],
|
disabled_property = Calculation(calc_value,
|
||||||
requires=[{'option': intoption, 'expected': 1, 'action': 'disabled'}], multi=True)
|
Params(ParamValue('disabled'),
|
||||||
|
kwargs={'condition': ParamOption(intoption),
|
||||||
|
'expected': ParamValue(1)}))
|
||||||
|
stroption = StrOption('str', 'Test string option', default=["abc"], properties=(disabled_property,), multi=True)
|
||||||
descr = OptionDescription("opt", "", [stroption])
|
descr = OptionDescription("opt", "", [stroption])
|
||||||
descr2 = OptionDescription("opt2", "", [intoption, s, descr])
|
descr2 = OptionDescription("opt2", "", [intoption, s, descr])
|
||||||
cfg = Config(descr2)
|
cfg = Config(descr2)
|
||||||
|
@ -331,42 +360,54 @@ def test_multi_with_requires_with_disabled_in_another_group():
|
||||||
cfg.option('int').value.set(1)
|
cfg.option('int').value.set(1)
|
||||||
raises(PropertiesOptionError, "cfg.option('opt.str').value.set(['a', 'b'])")
|
raises(PropertiesOptionError, "cfg.option('opt.str').value.set(['a', 'b'])")
|
||||||
assert 'disabled' in cfg.unrestraint.option('opt.str').property.get()
|
assert 'disabled' in cfg.unrestraint.option('opt.str').property.get()
|
||||||
|
#
|
||||||
|
#
|
||||||
def test_multi_with_requires_that_is_multi():
|
#def test_multi_with_requires_that_is_multi():
|
||||||
b = IntOption('int', 'Test int option', default=[0], multi=True)
|
# b = IntOption('int', 'Test int option', default=[0], multi=True)
|
||||||
c = StrOption('str', 'Test string option', default=['abc'], requires=[{'option': b, 'expected': 1, 'action': 'hidden'}], multi=True)
|
# hidden_property = Calculation(calc_value,
|
||||||
descr = OptionDescription("opt", "", [b, c])
|
# Params(ParamValue('hidden'),
|
||||||
descr
|
# kwargs={'condition': ParamOption(b),
|
||||||
raises(ValueError, "Config(descr)")
|
# 'expected': ParamValue(1)}))
|
||||||
|
# c = StrOption('str', 'Test string option', default=['abc'], properties=(hidden_property,), multi=True)
|
||||||
|
# descr = OptionDescription("opt", "", [b, c])
|
||||||
def test_multi_with_requires_that_is_multi_inverse():
|
# descr
|
||||||
b = IntOption('int', 'Test int option', default=[0], multi=True)
|
# # FIXME: ValueError: requirement mal formés pour l'option "int" ne doit pas être une valeur multiple pour "str"
|
||||||
c = StrOption('str', 'Test string option', default=['abc'], requires=[{'option': b, 'expected': 0, 'action': 'hidden', 'inverse': True}], multi=True)
|
# raises(ValueError, "Config(descr)")
|
||||||
descr = OptionDescription("opt", "", [b, c])
|
#
|
||||||
descr
|
#
|
||||||
raises(ValueError, "Config(descr)")
|
#def test_multi_with_requires_that_is_multi_inverse():
|
||||||
|
# b = IntOption('int', 'Test int option', default=[0], multi=True)
|
||||||
|
# c = StrOption('str', 'Test string option', default=['abc'], requires=[{'option': b, 'expected': 0, 'action': 'hidden', 'inverse': True}], multi=True)
|
||||||
def test_multi_with_requires_that_is_leadership():
|
# descr = OptionDescription("opt", "", [b, c])
|
||||||
b = IntOption('int', 'Test int option', default=[0], multi=True)
|
# descr
|
||||||
c = StrOption('str', 'Test string option', requires=[{'option': b, 'expected': 1, 'action': 'hidden'}], multi=True)
|
# Config(descr)
|
||||||
descr = Leadership("int", "", [b, c])
|
# # FIXME: ValueError: requirement mal formés pour l'option "int" ne doit pas être une valeur multiple pour "str"
|
||||||
od = OptionDescription('root', '', [descr])
|
# raises(ValueError, "Config(descr)")
|
||||||
Config(od)
|
#
|
||||||
|
#
|
||||||
|
#def test_multi_with_requires_that_is_leadership():
|
||||||
def test_multi_with_requires_that_is_leadership_leader():
|
# b = IntOption('int', 'Test int option', default=[0], multi=True)
|
||||||
b = IntOption('int', 'Test int option', multi=True)
|
# c = StrOption('str', 'Test string option', requires=[{'option': b, 'expected': 1, 'action': 'hidden'}], multi=True)
|
||||||
c = StrOption('str', 'Test string option', requires=[{'option': b, 'expected': 1, 'action': 'hidden'}], multi=True)
|
# descr = Leadership("int", "", [b, c])
|
||||||
raises(ValueError, "Leadership('str', '', [c, b])")
|
# od = OptionDescription('root', '', [descr])
|
||||||
|
# Config(od)
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#def test_multi_with_requires_that_is_leadership_leader():
|
||||||
|
# b = IntOption('int', 'Test int option', multi=True)
|
||||||
|
# c = StrOption('str', 'Test string option', requires=[{'option': b, 'expected': 1, 'action': 'hidden'}], multi=True)
|
||||||
|
# raises(ValueError, "Leadership('str', '', [c, b])")
|
||||||
|
|
||||||
|
|
||||||
def test_multi_with_requires_that_is_leadership_follower():
|
def test_multi_with_requires_that_is_leadership_follower():
|
||||||
b = IntOption('int', 'Test int option', default=[0], multi=True)
|
b = IntOption('int', 'Test int option', default=[0], multi=True)
|
||||||
c = StrOption('str', 'Test string option', multi=True)
|
c = StrOption('str', 'Test string option', multi=True)
|
||||||
d = StrOption('str1', 'Test string option', requires=[{'option': c, 'expected': '1', 'action': 'hidden'}], multi=True)
|
hidden_property = Calculation(calc_value,
|
||||||
|
Params(ParamValue('hidden'),
|
||||||
|
kwargs={'condition': ParamOption(c),
|
||||||
|
'index': ParamIndex(),
|
||||||
|
'expected': ParamValue('1')}))
|
||||||
|
d = StrOption('str1', 'Test string option', properties=(hidden_property,), multi=True)
|
||||||
descr = Leadership("int", "", [b, c, d])
|
descr = Leadership("int", "", [b, c, d])
|
||||||
descr2 = OptionDescription('od', '', [descr])
|
descr2 = OptionDescription('od', '', [descr])
|
||||||
cfg = Config(descr2)
|
cfg = Config(descr2)
|
||||||
|
@ -392,7 +433,13 @@ def test_multi_with_requires_that_is_leadership_follower():
|
||||||
def test_multi_with_requires_that_is_leadership_follower_inverse():
|
def test_multi_with_requires_that_is_leadership_follower_inverse():
|
||||||
b = IntOption('int', 'Test int option', default=[0], multi=True)
|
b = IntOption('int', 'Test int option', default=[0], multi=True)
|
||||||
c = StrOption('str', 'Test string option', multi=True)
|
c = StrOption('str', 'Test string option', multi=True)
|
||||||
d = StrOption('str1', 'Test string option', requires=[{'option': c, 'expected': None, 'action': 'hidden', 'inverse': True}], multi=True)
|
hidden_property = Calculation(calc_value,
|
||||||
|
Params(ParamValue('hidden'),
|
||||||
|
kwargs={'condition': ParamOption(c),
|
||||||
|
'index': ParamIndex(),
|
||||||
|
'inverse_condition': ParamValue(True),
|
||||||
|
'expected': ParamValue(None)}))
|
||||||
|
d = StrOption('str1', 'Test string option', properties=(hidden_property,), multi=True)
|
||||||
descr = Leadership("int", "", [b, c, d])
|
descr = Leadership("int", "", [b, c, d])
|
||||||
descr2 = OptionDescription('od', '', [descr])
|
descr2 = OptionDescription('od', '', [descr])
|
||||||
cfg = Config(descr2)
|
cfg = Config(descr2)
|
||||||
|
@ -415,16 +462,22 @@ def test_multi_with_requires_that_is_leadership_follower_inverse():
|
||||||
raises(PropertiesOptionError, "cfg.option('int.str1', 1).value.get()")
|
raises(PropertiesOptionError, "cfg.option('int.str1', 1).value.get()")
|
||||||
|
|
||||||
|
|
||||||
def test_multi_with_requires_that_is_not_same_leadership():
|
#def test_multi_with_requires_that_is_not_same_leadership():
|
||||||
b = IntOption('int', 'Test int option', default=[0], multi=True)
|
# b = IntOption('int', 'Test int option', default=[0], multi=True)
|
||||||
c = StrOption('str', 'Test string option', requires=[{'option': b, 'expected': 1, 'action': 'hidden'}], multi=True)
|
# hidden_property = Calculation(calc_value,
|
||||||
descr1 = Leadership("int", "", [b, c])
|
# Params(ParamValue('hidden'),
|
||||||
d = IntOption('int1', 'Test int option', default=[0], multi=True)
|
# kwargs={'condition': ParamOption(b),
|
||||||
e = StrOption('str', 'Test string option', requires=[{'option': b, 'expected': 1, 'action': 'hidden'}], multi=True)
|
# 'index': ParamIndex(),
|
||||||
descr2 = Leadership("int1", "", [d, e])
|
# 'expected': ParamValue(1)}))
|
||||||
descr3 = OptionDescription('val', '', [descr1, descr2])
|
# c = StrOption('str', 'Test string option', properties=(hidden_property,), multi=True)
|
||||||
descr3
|
# #c = StrOption('str', 'Test string option', requires=[{'option': b, 'expected': 1, 'action': 'hidden'}], multi=True)
|
||||||
raises(ValueError, "Config(descr3)")
|
# descr1 = Leadership("int", "", [b, c])
|
||||||
|
# d = IntOption('int1', 'Test int option', default=[0], multi=True)
|
||||||
|
# e = StrOption('str', 'Test string option', requires=[{'option': b, 'expected': 1, 'action': 'hidden'}], multi=True)
|
||||||
|
# descr2 = Leadership("int1", "", [d, e])
|
||||||
|
# descr3 = OptionDescription('val', '', [descr1, descr2])
|
||||||
|
# descr3
|
||||||
|
# raises(ValueError, "Config(descr3)")
|
||||||
|
|
||||||
|
|
||||||
def test_multi_with_bool():
|
def test_multi_with_bool():
|
||||||
|
@ -606,17 +659,45 @@ def test_pprint():
|
||||||
s2 = StrOption("string2", "", default="string")
|
s2 = StrOption("string2", "", default="string")
|
||||||
s3 = StrOption("string3", "", default=["string"], default_multi="string", multi=True, properties=('hidden',))
|
s3 = StrOption("string3", "", default=["string"], default_multi="string", multi=True, properties=('hidden',))
|
||||||
intoption = IntOption('int', 'Test int option', default=0)
|
intoption = IntOption('int', 'Test int option', default=0)
|
||||||
stroption = StrOption('str', 'Test string option', default="abc",
|
hidden_property = Calculation(calc_value,
|
||||||
requires=[{'option': intoption, 'expected': 2, 'action': 'hidden', 'inverse': True},
|
Params(ParamValue('hidden'),
|
||||||
{'option': intoption, 'expected': 3, 'action': 'hidden', 'inverse': True},
|
kwargs={'condition': ParamOption(intoption, todict=True),
|
||||||
{'option': intoption, 'expected': 4, 'action': 'hidden', 'inverse': True},
|
'expected_0': ParamValue(2),
|
||||||
{'option': intoption, 'expected': 1, 'action': 'disabled'},
|
'expected_1': ParamValue(3),
|
||||||
{'option': s2, 'expected': 'string', 'action': 'disabled'}])
|
'expected_2': ParamValue(4),
|
||||||
|
'inverse_condition': ParamValue(True)}),
|
||||||
|
calc_value_property_help)
|
||||||
|
disabled_property = Calculation(calc_value,
|
||||||
|
Params(ParamValue('disabled'),
|
||||||
|
kwargs={'condition_0': ParamOption(intoption, todict=True),
|
||||||
|
'expected_0': ParamValue(1),
|
||||||
|
'condition_1': ParamOption(s2, todict=True),
|
||||||
|
'expected_1': ParamValue('string')}),
|
||||||
|
calc_value_property_help)
|
||||||
|
stroption = StrOption('str', 'Test string option', default="abc", properties=(hidden_property, disabled_property))
|
||||||
|
# requires=[{'option': intoption, 'expected': 2, 'action': 'hidden', 'inverse': True},
|
||||||
|
# {'option': intoption, 'expected': 3, 'action': 'hidden', 'inverse': True},
|
||||||
|
# {'option': intoption, 'expected': 4, 'action': 'hidden', 'inverse': True},
|
||||||
|
# {'option': intoption, 'expected': 1, 'action': 'disabled'},
|
||||||
|
# {'option': s2, 'expected': 'string', 'action': 'disabled'}])
|
||||||
|
|
||||||
val2 = StrOption('val2', "")
|
val2 = StrOption('val2', "")
|
||||||
descr2 = OptionDescription("options", "", [val2], requires=[{'option': intoption, 'expected': 1, 'action': 'hidden'}])
|
hidden_property = Calculation(calc_value,
|
||||||
|
Params(ParamValue('hidden'),
|
||||||
|
kwargs={'condition': ParamOption(intoption, todict=True),
|
||||||
|
'expected': ParamValue(1)}),
|
||||||
|
calc_value_property_help)
|
||||||
|
descr2 = OptionDescription("options", "", [val2], properties=(hidden_property,))
|
||||||
|
#descr2 = OptionDescription("options", "", [val2], requires=[{'option': intoption, 'expected': 1, 'action': 'hidden'}])
|
||||||
|
|
||||||
val3 = StrOption('val3', "", requires=[{'option': stroption, 'expected': '2', 'action': 'hidden', 'inverse': True}])
|
hidden_property = Calculation(calc_value,
|
||||||
|
Params(ParamValue('hidden'),
|
||||||
|
kwargs={'condition': ParamOption(stroption, todict=True),
|
||||||
|
'expected': ParamValue('2'),
|
||||||
|
'inverse_condition': ParamValue(True)}),
|
||||||
|
calc_value_property_help)
|
||||||
|
val3 = StrOption('val3', "", properties=(hidden_property,))
|
||||||
|
#val3 = StrOption('val3', "", requires=[{'option': stroption, 'expected': '2', 'action': 'hidden', 'inverse': True}])
|
||||||
|
|
||||||
descr = OptionDescription("options", "", [s, s2, s3, intoption, stroption, descr2, val3])
|
descr = OptionDescription("options", "", [s, s2, s3, intoption, stroption, descr2, val3])
|
||||||
cfg = Config(descr)
|
cfg = Config(descr)
|
||||||
|
|
|
@ -7,7 +7,8 @@ from .config import config_type, get_config
|
||||||
from py.test import raises
|
from py.test import raises
|
||||||
|
|
||||||
from tiramisu import ChoiceOption, BoolOption, IntOption, FloatOption, \
|
from tiramisu import ChoiceOption, BoolOption, IntOption, FloatOption, \
|
||||||
PasswordOption, StrOption, DateOption, OptionDescription, Config
|
PasswordOption, StrOption, DateOption, OptionDescription, Config, \
|
||||||
|
Calculation, Params, ParamOption, ParamValue, calc_value
|
||||||
from tiramisu.error import PropertiesOptionError
|
from tiramisu.error import PropertiesOptionError
|
||||||
from tiramisu.storage import list_sessions
|
from tiramisu.storage import list_sessions
|
||||||
|
|
||||||
|
@ -26,11 +27,17 @@ def make_description():
|
||||||
floatoption = FloatOption('float', 'Test float option', default=2.3)
|
floatoption = FloatOption('float', 'Test float option', default=2.3)
|
||||||
stroption = StrOption('str', 'Test string option', default="abc")
|
stroption = StrOption('str', 'Test string option', default="abc")
|
||||||
|
|
||||||
wantref_option = BoolOption('wantref', 'Test requires', default=False,
|
hidden_property = Calculation(calc_value,
|
||||||
requires=({'option': gcoption, 'expected': 'ref', 'action': 'hidden'},))
|
Params(ParamValue('hidden'),
|
||||||
|
kwargs={'condition': ParamOption(gcoption),
|
||||||
|
'expected': ParamValue('ref')}))
|
||||||
|
wantref_option = BoolOption('wantref', 'Test requires', default=False, properties=(hidden_property,))
|
||||||
|
hidden_property = Calculation(calc_value,
|
||||||
|
Params(ParamValue('hidden'),
|
||||||
|
kwargs={'condition': ParamOption(gcoption),
|
||||||
|
'expected': ParamValue('framework')}))
|
||||||
wantframework_option = BoolOption('wantframework', 'Test requires',
|
wantframework_option = BoolOption('wantframework', 'Test requires',
|
||||||
default=False,
|
default=False, properties=(hidden_property,))
|
||||||
requires=({'option': gcoption, 'expected': 'framework', 'action': 'hidden'},))
|
|
||||||
|
|
||||||
# ____________________________________________________________
|
# ____________________________________________________________
|
||||||
booloptiontwo = BoolOption('booltwo', 'Test boolean option two', default=False)
|
booloptiontwo = BoolOption('booltwo', 'Test boolean option two', default=False)
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,9 +1,8 @@
|
||||||
#from autopath import do_autopath
|
#from autopath import do_autopath
|
||||||
#do_autopath()
|
#do_autopath()
|
||||||
#
|
#
|
||||||
from tiramisu.option import BoolOption, UnicodeOption, SymLinkOption, \
|
from tiramisu import BoolOption, UnicodeOption, SymLinkOption, OptionDescription, DynOptionDescription, \
|
||||||
OptionDescription, DynOptionDescription
|
Calculation, Params, ParamOption, ParamValue, calc_value, Config
|
||||||
from tiramisu import Config
|
|
||||||
from pickle import dumps
|
from pickle import dumps
|
||||||
from py.test import raises
|
from py.test import raises
|
||||||
import sys
|
import sys
|
||||||
|
@ -213,7 +212,12 @@ def _diff_conf(cfg1, cfg2):
|
||||||
|
|
||||||
def test_diff_opt():
|
def test_diff_opt():
|
||||||
b = BoolOption('b', '')
|
b = BoolOption('b', '')
|
||||||
u = UnicodeOption('u', '', requires=[{'option': b, 'expected': True, 'action': 'disabled', 'inverse': True}])
|
disabled_property = Calculation(calc_value,
|
||||||
|
Params(ParamValue('disabled'),
|
||||||
|
kwargs={'condition': ParamOption(b),
|
||||||
|
'expected': ParamValue(True),
|
||||||
|
'inverse_condition': ParamValue(True)}))
|
||||||
|
u = UnicodeOption('u', '', properties=(disabled_property,))
|
||||||
s = SymLinkOption('s', u)
|
s = SymLinkOption('s', u)
|
||||||
o = OptionDescription('o', '', [b, u, s])
|
o = OptionDescription('o', '', [b, u, s])
|
||||||
o1 = OptionDescription('o1', '', [o])
|
o1 = OptionDescription('o1', '', [o])
|
||||||
|
|
|
@ -5,7 +5,7 @@ do_autopath()
|
||||||
from .config import config_type, get_config
|
from .config import config_type, get_config
|
||||||
|
|
||||||
from tiramisu import BoolOption, StrOption, SymLinkOption, \
|
from tiramisu import BoolOption, StrOption, SymLinkOption, \
|
||||||
OptionDescription, Leadership, Config
|
OptionDescription, Leadership, Config, Calculation, calc_value, Params, ParamOption, ParamValue
|
||||||
from tiramisu.error import PropertiesOptionError, ConfigError
|
from tiramisu.error import PropertiesOptionError, ConfigError
|
||||||
from tiramisu.setting import groups, owners
|
from tiramisu.setting import groups, owners
|
||||||
from tiramisu.storage import list_sessions
|
from tiramisu.storage import list_sessions
|
||||||
|
@ -122,9 +122,11 @@ def test_symlink_getcallback():
|
||||||
|
|
||||||
def test_symlink_requires(config_type):
|
def test_symlink_requires(config_type):
|
||||||
boolopt = BoolOption('b', '', default=True)
|
boolopt = BoolOption('b', '', default=True)
|
||||||
stropt = StrOption('s', '', requires=[{'option': boolopt,
|
disabled_property = Calculation(calc_value,
|
||||||
'expected': False,
|
Params(ParamValue('disabled'),
|
||||||
'action': 'disabled'}])
|
kwargs={'condition': ParamOption(boolopt),
|
||||||
|
'expected': ParamValue(False)}))
|
||||||
|
stropt = StrOption('s', '', properties=(disabled_property,))
|
||||||
linkopt = SymLinkOption("c", stropt)
|
linkopt = SymLinkOption("c", stropt)
|
||||||
descr = OptionDescription('opt', '', [boolopt, stropt, linkopt])
|
descr = OptionDescription('opt', '', [boolopt, stropt, linkopt])
|
||||||
cfg = Config(descr)
|
cfg = Config(descr)
|
||||||
|
|
|
@ -14,8 +14,8 @@
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
"""Configuration management library written in python
|
"""Configuration management library written in python
|
||||||
"""
|
"""
|
||||||
from .function import Params, ParamOption, ParamValue, ParamContext, \
|
from .function import tiramisu_copy, calc_value, calc_value_property_help
|
||||||
tiramisu_copy, calc_value
|
from .autolib import Calculation, Params, ParamOption, ParamSelfOption, ParamValue, ParamIndex, ParamContext
|
||||||
from .option import *
|
from .option import *
|
||||||
from .error import APIError
|
from .error import APIError
|
||||||
from .api import Config, MetaConfig, GroupConfig, MixConfig
|
from .api import Config, MetaConfig, GroupConfig, MixConfig
|
||||||
|
@ -25,9 +25,12 @@ from .storage import default_storage, Storage, list_sessions, \
|
||||||
delete_session
|
delete_session
|
||||||
|
|
||||||
|
|
||||||
allfuncs = ['Params',
|
allfuncs = ['Calculation',
|
||||||
'ParamOption',
|
'Params',
|
||||||
|
'ParamOption',
|
||||||
|
'ParamSelfOption',
|
||||||
'ParamValue',
|
'ParamValue',
|
||||||
|
'ParamIndex',
|
||||||
'ParamContext',
|
'ParamContext',
|
||||||
'MetaConfig',
|
'MetaConfig',
|
||||||
'MixConfig',
|
'MixConfig',
|
||||||
|
@ -40,7 +43,8 @@ allfuncs = ['Params',
|
||||||
'list_sessions',
|
'list_sessions',
|
||||||
'delete_session',
|
'delete_session',
|
||||||
'tiramisu_copy',
|
'tiramisu_copy',
|
||||||
'calc_value']
|
'calc_value',
|
||||||
|
'calc_value_property_help']
|
||||||
allfuncs.extend(all_options)
|
allfuncs.extend(all_options)
|
||||||
del(all_options)
|
del(all_options)
|
||||||
__all__ = tuple(allfuncs)
|
__all__ = tuple(allfuncs)
|
||||||
|
|
|
@ -384,8 +384,6 @@ class TiramisuOptionProperty(CommonTiramisuOption):
|
||||||
def get(self,
|
def get(self,
|
||||||
only_raises=False):
|
only_raises=False):
|
||||||
"""Get properties for an option"""
|
"""Get properties for an option"""
|
||||||
option = self._option_bag.option
|
|
||||||
#self._test_follower_index()
|
|
||||||
if not only_raises:
|
if not only_raises:
|
||||||
return self._option_bag.properties
|
return self._option_bag.properties
|
||||||
# do not check cache properties/permissives which are not save (unrestraint, ...)
|
# do not check cache properties/permissives which are not save (unrestraint, ...)
|
||||||
|
@ -397,8 +395,8 @@ class TiramisuOptionProperty(CommonTiramisuOption):
|
||||||
if prop in FORBIDDEN_SET_PROPERTIES:
|
if prop in FORBIDDEN_SET_PROPERTIES:
|
||||||
raise ConfigError(_('cannot add this property: "{0}"').format(
|
raise ConfigError(_('cannot add this property: "{0}"').format(
|
||||||
' '.join(prop)))
|
' '.join(prop)))
|
||||||
props = self._settings.getproperties(self._option_bag,
|
props = self._settings._p_.getproperties(self._option_bag.path,
|
||||||
apply_requires=False)
|
option.impl_getproperties())
|
||||||
self._settings.setproperties(self._option_bag.path,
|
self._settings.setproperties(self._option_bag.path,
|
||||||
props | {prop},
|
props | {prop},
|
||||||
self._option_bag,
|
self._option_bag,
|
||||||
|
@ -407,8 +405,8 @@ class TiramisuOptionProperty(CommonTiramisuOption):
|
||||||
def pop(self, prop):
|
def pop(self, prop):
|
||||||
"""Remove new property for an option"""
|
"""Remove new property for an option"""
|
||||||
option = self._option_bag.option
|
option = self._option_bag.option
|
||||||
props = self._settings.getproperties(self._option_bag,
|
props = self._settings._p_.getproperties(self._option_bag.path,
|
||||||
apply_requires=False)
|
option.impl_getproperties())
|
||||||
self._settings.setproperties(self._option_bag.path,
|
self._settings.setproperties(self._option_bag.path,
|
||||||
props - {prop},
|
props - {prop},
|
||||||
self._option_bag,
|
self._option_bag,
|
||||||
|
|
|
@ -19,22 +19,159 @@
|
||||||
# ____________________________________________________________
|
# ____________________________________________________________
|
||||||
"enables us to carry out a calculation and return an option's value"
|
"enables us to carry out a calculation and return an option's value"
|
||||||
from typing import Any, Optional, Union, Callable, Dict, List
|
from typing import Any, Optional, Union, Callable, Dict, List
|
||||||
|
from itertools import chain
|
||||||
|
|
||||||
from .error import PropertiesOptionError, ConfigError, LeadershipError
|
from .error import PropertiesOptionError, ConfigError, LeadershipError
|
||||||
from .i18n import _
|
from .i18n import _
|
||||||
from .setting import undefined, ConfigBag, OptionBag, Undefined
|
from .setting import undefined, ConfigBag, OptionBag, Undefined
|
||||||
from .storage import get_default_values_storages, get_default_settings_storages
|
from .storage import get_default_values_storages, get_default_settings_storages
|
||||||
from .function import ParamValue, ParamContext, ParamIndex, ParamOption, Params
|
|
||||||
# ____________________________________________________________
|
# ____________________________________________________________
|
||||||
|
|
||||||
|
|
||||||
|
class Params:
|
||||||
|
__slots__ = ('args', 'kwargs')
|
||||||
|
def __init__(self, args=None, kwargs=None, **kwgs):
|
||||||
|
if args is None:
|
||||||
|
args = tuple()
|
||||||
|
if kwargs is None:
|
||||||
|
kwargs = {}
|
||||||
|
if kwgs:
|
||||||
|
kwargs.update(kwgs)
|
||||||
|
if isinstance(args, Param):
|
||||||
|
args = (args,)
|
||||||
|
else:
|
||||||
|
if not isinstance(args, tuple):
|
||||||
|
raise ValueError(_('args in params must be a tuple'))
|
||||||
|
for arg in args:
|
||||||
|
if not isinstance(arg, Param):
|
||||||
|
raise ValueError(_('arg in params must be a Param'))
|
||||||
|
if not isinstance(kwargs, dict):
|
||||||
|
raise ValueError(_('kwargs in params must be a dict'))
|
||||||
|
for arg in kwargs.values():
|
||||||
|
if not isinstance(arg, Param):
|
||||||
|
raise ValueError(_('arg in params must be a Param'))
|
||||||
|
self.args = args
|
||||||
|
self.kwargs = kwargs
|
||||||
|
|
||||||
|
|
||||||
|
class Param:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ParamOption(Param):
|
||||||
|
__slots__ = ('todict',
|
||||||
|
'error',
|
||||||
|
'option',
|
||||||
|
'notraisepropertyerror',
|
||||||
|
'raisepropertyerror')
|
||||||
|
def __init__(self,
|
||||||
|
option: 'Option',
|
||||||
|
notraisepropertyerror: bool=False,
|
||||||
|
raisepropertyerror: bool=False,
|
||||||
|
todict: bool=False) -> None:
|
||||||
|
if __debug__ and not hasattr(option, 'impl_is_symlinkoption'):
|
||||||
|
raise ValueError(_('paramoption needs an option not {}').format(type(option)))
|
||||||
|
if option.impl_is_symlinkoption():
|
||||||
|
cur_opt = option.impl_getopt()
|
||||||
|
else:
|
||||||
|
cur_opt = option
|
||||||
|
assert isinstance(notraisepropertyerror, bool), _('param must have a boolean not a {} for notraisepropertyerror').format(type(notraisepropertyerror))
|
||||||
|
assert isinstance(raisepropertyerror, bool), _('param must have a boolean not a {} for raisepropertyerror').format(type(raisepropertyerror))
|
||||||
|
self.todict = todict
|
||||||
|
self.option = cur_opt
|
||||||
|
self.notraisepropertyerror = notraisepropertyerror
|
||||||
|
self.raisepropertyerror = raisepropertyerror
|
||||||
|
|
||||||
|
|
||||||
|
class ParamSelfOption(Param):
|
||||||
|
__slots__ = ('todict',)
|
||||||
|
def __init__(self,
|
||||||
|
todict: bool=False) -> None:
|
||||||
|
self.todict = todict
|
||||||
|
|
||||||
|
|
||||||
|
class ParamValue(Param):
|
||||||
|
__slots__ = ('value',)
|
||||||
|
def __init__(self, value):
|
||||||
|
self.value = value
|
||||||
|
|
||||||
|
|
||||||
|
class ParamContext(Param):
|
||||||
|
__slots__ = tuple()
|
||||||
|
|
||||||
|
|
||||||
|
class ParamIndex(Param):
|
||||||
|
__slots__ = tuple()
|
||||||
|
|
||||||
|
|
||||||
|
class Calculation:
|
||||||
|
__slots__ = ('function',
|
||||||
|
'params',
|
||||||
|
'help_function',
|
||||||
|
'has_index')
|
||||||
|
def __init__(self,
|
||||||
|
function: Callable,
|
||||||
|
params: Optional[Params]=None,
|
||||||
|
help_function: Optional[Callable]=None):
|
||||||
|
assert isinstance(function, Callable), _('first argument ({0}) must be a function').format(function)
|
||||||
|
if help_function:
|
||||||
|
assert isinstance(help_function, Callable), _('help_function ({0}) must be a function').format(help_function)
|
||||||
|
self.help_function = help_function
|
||||||
|
else:
|
||||||
|
self.help_function = None
|
||||||
|
self.function = function
|
||||||
|
if params:
|
||||||
|
self.params = params
|
||||||
|
for arg in chain(self.params.args, self.params.kwargs.values()):
|
||||||
|
if isinstance(arg, ParamIndex):
|
||||||
|
self.has_index = True
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
self.has_index = False
|
||||||
|
else:
|
||||||
|
self.has_index = False
|
||||||
|
|
||||||
|
def execute(self,
|
||||||
|
option_bag: OptionBag,
|
||||||
|
leadership_must_have_index: bool=False) -> Any:
|
||||||
|
if leadership_must_have_index and not self.has_index:
|
||||||
|
leadership_must_have_index = False
|
||||||
|
return carry_out_calculation(option_bag.option,
|
||||||
|
callback=self.function,
|
||||||
|
callback_params=self.params,
|
||||||
|
index=option_bag.index,
|
||||||
|
config_bag=option_bag.config_bag,
|
||||||
|
fromconsistency=option_bag.fromconsistency,
|
||||||
|
leadership_must_have_index=leadership_must_have_index)
|
||||||
|
|
||||||
|
def help(self,
|
||||||
|
option_bag: OptionBag,
|
||||||
|
leadership_must_have_index: bool=False) -> str:
|
||||||
|
if not self.help_function:
|
||||||
|
return self.execute(option_bag,
|
||||||
|
leadership_must_have_index=leadership_must_have_index)
|
||||||
|
if leadership_must_have_index and not self.has_index:
|
||||||
|
leadership_must_have_index = False
|
||||||
|
return carry_out_calculation(option_bag.option,
|
||||||
|
callback=self.help_function,
|
||||||
|
callback_params=self.params,
|
||||||
|
index=option_bag.index,
|
||||||
|
config_bag=option_bag.config_bag,
|
||||||
|
fromconsistency=option_bag.fromconsistency,
|
||||||
|
leadership_must_have_index=leadership_must_have_index)
|
||||||
|
|
||||||
|
|
||||||
|
class Break(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def manager_callback(callbk: Union[ParamOption, ParamValue],
|
def manager_callback(callbk: Union[ParamOption, ParamValue],
|
||||||
option,
|
option,
|
||||||
index: Optional[int],
|
index: Optional[int],
|
||||||
orig_value,
|
orig_value,
|
||||||
config_bag: ConfigBag,
|
config_bag: ConfigBag,
|
||||||
fromconsistency: List) -> Any:
|
fromconsistency: List,
|
||||||
|
leadership_must_have_index: bool) -> Any:
|
||||||
"""replace Param by true value"""
|
"""replace Param by true value"""
|
||||||
if isinstance(callbk, ParamValue):
|
if isinstance(callbk, ParamValue):
|
||||||
return callbk.value
|
return callbk.value
|
||||||
|
@ -46,17 +183,24 @@ def manager_callback(callbk: Union[ParamOption, ParamValue],
|
||||||
# Not an option, set full context
|
# Not an option, set full context
|
||||||
return config_bag.context.duplicate(force_values=get_default_values_storages(),
|
return config_bag.context.duplicate(force_values=get_default_values_storages(),
|
||||||
force_settings=get_default_settings_storages())
|
force_settings=get_default_settings_storages())
|
||||||
opt = callbk.option
|
if isinstance(callbk, ParamSelfOption):
|
||||||
|
opt = option
|
||||||
|
else:
|
||||||
|
# it's ParamOption
|
||||||
|
opt = callbk.option
|
||||||
if opt.issubdyn():
|
if opt.issubdyn():
|
||||||
opt = opt.to_dynoption(option.rootpath,
|
opt = opt.to_dynoption(option.rootpath,
|
||||||
option.impl_getsuffix())
|
option.impl_getsuffix())
|
||||||
path = opt.impl_getpath()
|
path = opt.impl_getpath()
|
||||||
|
is_follower = opt.impl_is_follower()
|
||||||
|
if leadership_must_have_index and opt.impl_get_leadership() and index is None:
|
||||||
|
raise Break()
|
||||||
if index is not None and opt.impl_get_leadership() and \
|
if index is not None and opt.impl_get_leadership() and \
|
||||||
opt.impl_get_leadership().in_same_group(option):
|
opt.impl_get_leadership().in_same_group(option):
|
||||||
if opt == option:
|
if opt == option:
|
||||||
index_ = None
|
index_ = None
|
||||||
with_index = False
|
with_index = False
|
||||||
elif opt.impl_is_follower():
|
elif is_follower:
|
||||||
index_ = index
|
index_ = index
|
||||||
with_index = False
|
with_index = False
|
||||||
else:
|
else:
|
||||||
|
@ -66,35 +210,43 @@ def manager_callback(callbk: Union[ParamOption, ParamValue],
|
||||||
index_ = None
|
index_ = None
|
||||||
with_index = False
|
with_index = False
|
||||||
if opt == option and orig_value is not undefined and \
|
if opt == option and orig_value is not undefined and \
|
||||||
(not opt.impl_is_follower() or index is None):
|
(not is_follower or index is None):
|
||||||
return orig_value
|
value = orig_value
|
||||||
# don't validate if option is option that we tried to validate
|
else:
|
||||||
config_bag = config_bag.copy()
|
# don't validate if option is option that we tried to validate
|
||||||
config_bag.set_permissive()
|
config_bag = config_bag.copy()
|
||||||
config_bag.properties -= {'warnings'}
|
config_bag.properties = config_bag.true_properties - {'warnings'}
|
||||||
option_bag = OptionBag()
|
config_bag.set_permissive()
|
||||||
option_bag.set_option(opt,
|
#config_bag.properties -= {'warnings'}
|
||||||
path,
|
option_bag = OptionBag()
|
||||||
index_,
|
option_bag.set_option(opt,
|
||||||
config_bag)
|
path,
|
||||||
if fromconsistency:
|
index_,
|
||||||
option_bag.fromconsistency = fromconsistency.copy()
|
config_bag)
|
||||||
if opt == option:
|
if fromconsistency:
|
||||||
option_bag.config_bag.unrestraint()
|
option_bag.fromconsistency = fromconsistency.copy()
|
||||||
option_bag.config_bag.remove_validation()
|
if opt == option:
|
||||||
try:
|
option_bag.config_bag.unrestraint()
|
||||||
# get value
|
option_bag.config_bag.remove_validation()
|
||||||
value = config_bag.context.getattr(path,
|
# if we are in properties calculation, cannot calculated properties
|
||||||
option_bag)
|
option_bag.properties = config_bag.context.cfgimpl_get_settings().getproperties(option_bag,
|
||||||
if with_index:
|
apply_requires=False)
|
||||||
return value[index]
|
try:
|
||||||
|
# get value
|
||||||
|
value = config_bag.context.getattr(path,
|
||||||
|
option_bag)
|
||||||
|
if with_index:
|
||||||
|
value = value[index]
|
||||||
|
except PropertiesOptionError as err:
|
||||||
|
# raise PropertiesOptionError (which is catched) because must not add value None in carry_out_calculation
|
||||||
|
if callbk.notraisepropertyerror or callbk.raisepropertyerror:
|
||||||
|
raise err
|
||||||
|
raise ConfigError(_('unable to carry out a calculation for "{}"'
|
||||||
|
', {}').format(option.impl_get_display_name(), err), err)
|
||||||
|
if not callbk.todict:
|
||||||
return value
|
return value
|
||||||
except PropertiesOptionError as err:
|
return {'name': opt.impl_get_display_name(),
|
||||||
# raise PropertiesOptionError (which is catched) because must not add value None in carry_out_calculation
|
'value': value}
|
||||||
if callbk.notraisepropertyerror:
|
|
||||||
raise err
|
|
||||||
raise ConfigError(_('unable to carry out a calculation for "{}"'
|
|
||||||
', {}').format(option.impl_get_display_name(), err), err)
|
|
||||||
|
|
||||||
|
|
||||||
def carry_out_calculation(option,
|
def carry_out_calculation(option,
|
||||||
|
@ -104,8 +256,8 @@ def carry_out_calculation(option,
|
||||||
config_bag: Optional[ConfigBag],
|
config_bag: Optional[ConfigBag],
|
||||||
fromconsistency: List,
|
fromconsistency: List,
|
||||||
orig_value=undefined,
|
orig_value=undefined,
|
||||||
|
leadership_must_have_index: bool=False,
|
||||||
is_validator: int=False):
|
is_validator: int=False):
|
||||||
|
|
||||||
"""a function that carries out a calculation for an option's value
|
"""a function that carries out a calculation for an option's value
|
||||||
|
|
||||||
:param option: the option
|
:param option: the option
|
||||||
|
@ -227,12 +379,18 @@ def carry_out_calculation(option,
|
||||||
index,
|
index,
|
||||||
orig_value,
|
orig_value,
|
||||||
config_bag,
|
config_bag,
|
||||||
fromconsistency)
|
fromconsistency,
|
||||||
|
leadership_must_have_index)
|
||||||
if value is undefined:
|
if value is undefined:
|
||||||
return undefined
|
return undefined
|
||||||
args.append(value)
|
args.append(value)
|
||||||
except PropertiesOptionError:
|
except PropertiesOptionError as err:
|
||||||
pass
|
if callbk.raisepropertyerror:
|
||||||
|
raise err
|
||||||
|
if callbk.todict:
|
||||||
|
args.append({'propertyerror': str(err)})
|
||||||
|
except Break:
|
||||||
|
continue
|
||||||
for key, callbk in callback_params.kwargs.items():
|
for key, callbk in callback_params.kwargs.items():
|
||||||
try:
|
try:
|
||||||
value = manager_callback(callbk,
|
value = manager_callback(callbk,
|
||||||
|
@ -240,12 +398,18 @@ def carry_out_calculation(option,
|
||||||
index,
|
index,
|
||||||
orig_value,
|
orig_value,
|
||||||
config_bag,
|
config_bag,
|
||||||
fromconsistency)
|
fromconsistency,
|
||||||
|
leadership_must_have_index)
|
||||||
if value is undefined:
|
if value is undefined:
|
||||||
return undefined
|
return undefined
|
||||||
kwargs[key] = value
|
kwargs[key] = value
|
||||||
except PropertiesOptionError:
|
except PropertiesOptionError as err:
|
||||||
pass
|
if callbk.raisepropertyerror:
|
||||||
|
raise err
|
||||||
|
if callbk.todict:
|
||||||
|
kwargs[key] = {'propertyerror': str(err)}
|
||||||
|
except Break:
|
||||||
|
continue
|
||||||
ret = calculate(option,
|
ret = calculate(option,
|
||||||
callback,
|
callback,
|
||||||
is_validator,
|
is_validator,
|
||||||
|
@ -290,6 +454,8 @@ def calculate(option,
|
||||||
raise err
|
raise err
|
||||||
error = err
|
error = err
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
|
#import traceback
|
||||||
|
#traceback.print_exc()
|
||||||
error = err
|
error = err
|
||||||
if args or kwargs:
|
if args or kwargs:
|
||||||
msg = _('unexpected error "{0}" in function "{1}" with arguments "{3}" and "{4}" '
|
msg = _('unexpected error "{0}" in function "{1}" with arguments "{3}" and "{4}" '
|
||||||
|
|
|
@ -269,10 +269,9 @@ class SubConfig(object):
|
||||||
def getattr(self,
|
def getattr(self,
|
||||||
name,
|
name,
|
||||||
option_bag,
|
option_bag,
|
||||||
from_follower=False):
|
from_follower=False,
|
||||||
|
needs_re_verify_follower_properties=False):
|
||||||
"""
|
"""
|
||||||
attribute notation mechanism for accessing the value of an option
|
|
||||||
:param name: attribute name
|
|
||||||
:return: option's value if name is an option name, OptionDescription
|
:return: option's value if name is an option name, OptionDescription
|
||||||
otherwise
|
otherwise
|
||||||
"""
|
"""
|
||||||
|
@ -298,7 +297,7 @@ class SubConfig(object):
|
||||||
return context.getattr(soption_bag.path,
|
return context.getattr(soption_bag.path,
|
||||||
soption_bag)
|
soption_bag)
|
||||||
|
|
||||||
if not from_follower or option_bag.option.impl_getrequires():
|
if not from_follower or needs_re_verify_follower_properties:
|
||||||
self.cfgimpl_get_settings().validate_properties(option_bag)
|
self.cfgimpl_get_settings().validate_properties(option_bag)
|
||||||
|
|
||||||
if option.impl_is_follower() and not from_follower:
|
if option.impl_is_follower() and not from_follower:
|
||||||
|
@ -311,6 +310,8 @@ class SubConfig(object):
|
||||||
length,
|
length,
|
||||||
option_bag.index))
|
option_bag.index))
|
||||||
if option.impl_is_follower() and option_bag.index is None:
|
if option.impl_is_follower() and option_bag.index is None:
|
||||||
|
needs_re_verify_follower_properties = option_bag.option.impl_getrequires() or \
|
||||||
|
self.cfgimpl_get_settings().has_properties_index(option_bag)
|
||||||
value = []
|
value = []
|
||||||
for idx in range(length):
|
for idx in range(length):
|
||||||
soption_bag = OptionBag()
|
soption_bag = OptionBag()
|
||||||
|
@ -322,7 +323,8 @@ class SubConfig(object):
|
||||||
try:
|
try:
|
||||||
value.append(self.getattr(name,
|
value.append(self.getattr(name,
|
||||||
soption_bag,
|
soption_bag,
|
||||||
from_follower=True))
|
from_follower=True,
|
||||||
|
needs_re_verify_follower_properties=needs_re_verify_follower_properties))
|
||||||
except PropertiesOptionError as err:
|
except PropertiesOptionError as err:
|
||||||
value.append(err)
|
value.append(err)
|
||||||
else:
|
else:
|
||||||
|
@ -412,40 +414,7 @@ class SubConfig(object):
|
||||||
withoption=None,
|
withoption=None,
|
||||||
withvalue=undefined,
|
withvalue=undefined,
|
||||||
fullpath=False):
|
fullpath=False):
|
||||||
"""exports the whole config into a `dict`, for example:
|
"""exports the whole config into a `dict`
|
||||||
|
|
||||||
>>> print(cfg.make_dict())
|
|
||||||
{'od2.var4': None, 'od2.var5': None, 'od2.var6': None}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
:param flatten: returns a dict(name=value) instead of a dict(path=value)
|
|
||||||
::
|
|
||||||
|
|
||||||
>>> print(cfg.make_dict(flatten=True))
|
|
||||||
{'var5': None, 'var4': None, 'var6': None}
|
|
||||||
|
|
||||||
:param withoption: returns the options that are present in the very same
|
|
||||||
`OptionDescription` than the `withoption` itself::
|
|
||||||
|
|
||||||
>>> print(cfg.make_dict(withoption='var1'))
|
|
||||||
{'od2.var4': None, 'od2.var5': None,
|
|
||||||
'od2.var6': None,
|
|
||||||
'od2.var1': u'value',
|
|
||||||
'od1.var1': None,
|
|
||||||
'od1.var3': None,
|
|
||||||
'od1.var2': None}
|
|
||||||
|
|
||||||
:param withvalue: returns the options that have the value `withvalue`
|
|
||||||
::
|
|
||||||
|
|
||||||
>>> print(c.make_dict(withoption='var1',
|
|
||||||
withvalue=u'value'))
|
|
||||||
{'od2.var4': None,
|
|
||||||
'od2.var5': None,
|
|
||||||
'od2.var6': None,
|
|
||||||
'od2.var1': u'value'}
|
|
||||||
|
|
||||||
:returns: dict of Option's name (or path) and values
|
:returns: dict of Option's name (or path) and values
|
||||||
"""
|
"""
|
||||||
pathsvalues = {}
|
pathsvalues = {}
|
||||||
|
|
|
@ -30,7 +30,7 @@ def display_list(lst, separator='and', add_quote=False):
|
||||||
ret = lst[0]
|
ret = lst[0]
|
||||||
if not isinstance(ret, str):
|
if not isinstance(ret, str):
|
||||||
ret = str(ret)
|
ret = str(ret)
|
||||||
if add_quote:
|
if add_quote and not ret.startswith('"'):
|
||||||
ret = '"{}"'.format(ret)
|
ret = '"{}"'.format(ret)
|
||||||
return ret
|
return ret
|
||||||
else:
|
else:
|
||||||
|
@ -39,13 +39,13 @@ def display_list(lst, separator='and', add_quote=False):
|
||||||
for l in lst[:-1]:
|
for l in lst[:-1]:
|
||||||
if not isinstance(l, str):
|
if not isinstance(l, str):
|
||||||
l = str(l)
|
l = str(l)
|
||||||
if add_quote:
|
if add_quote and not l.startswith('"'):
|
||||||
l = '"{}"'.format(l)
|
l = '"{}"'.format(l)
|
||||||
lst_.append(_(l))
|
lst_.append(_(l))
|
||||||
last = lst[-1]
|
last = lst[-1]
|
||||||
if not isinstance(last, str):
|
if not isinstance(last, str):
|
||||||
last = str(_(last))
|
last = str(_(last))
|
||||||
if add_quote:
|
if add_quote and not last.startswith('"'):
|
||||||
last = '"{}"'.format(last)
|
last = '"{}"'.format(last)
|
||||||
return ', '.join(lst_) + _(' {} ').format(separator) + '{}'.format(last)
|
return ', '.join(lst_) + _(' {} ').format(separator) + '{}'.format(last)
|
||||||
|
|
||||||
|
@ -91,7 +91,6 @@ class PropertiesOptionError(AttributeError):
|
||||||
return 'error'
|
return 'error'
|
||||||
req = self._settings.apply_requires(self._option_bag,
|
req = self._settings.apply_requires(self._option_bag,
|
||||||
True)
|
True)
|
||||||
#if req != {} or self._orig_opt is not None:
|
|
||||||
if req != {}:
|
if req != {}:
|
||||||
only_one = len(req) == 1
|
only_one = len(req) == 1
|
||||||
msg = []
|
msg = []
|
||||||
|
@ -99,8 +98,16 @@ class PropertiesOptionError(AttributeError):
|
||||||
msg.append('"{0}" ({1})'.format(action, display_list(msg_, add_quote=False)))
|
msg.append('"{0}" ({1})'.format(action, display_list(msg_, add_quote=False)))
|
||||||
msg = display_list(msg, add_quote=False)
|
msg = display_list(msg, add_quote=False)
|
||||||
else:
|
else:
|
||||||
only_one = len(self.proptype) == 1
|
properties = list(self._settings.calc_raises_properties(self._option_bag,
|
||||||
msg = display_list(list(self.proptype), add_quote=True)
|
apply_requires=False))
|
||||||
|
for property_ in self._settings.get_calculated_properties(self._option_bag):
|
||||||
|
properties.append(property_.help(self._option_bag))
|
||||||
|
|
||||||
|
if not properties:
|
||||||
|
# if proptype == ['mandatory']
|
||||||
|
properties = self.proptype
|
||||||
|
only_one = len(properties) == 1
|
||||||
|
msg = display_list(properties, add_quote=True)
|
||||||
if only_one:
|
if only_one:
|
||||||
prop_msg = _('property')
|
prop_msg = _('property')
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -14,276 +14,305 @@
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
from typing import Any, List, Optional
|
from typing import Any, List, Optional
|
||||||
from operator import add, mul, sub, truediv
|
from operator import add, mul, sub, truediv
|
||||||
from .setting import undefined
|
|
||||||
from .i18n import _
|
from .i18n import _
|
||||||
|
from .setting import undefined
|
||||||
|
from .error import display_list
|
||||||
class Params:
|
|
||||||
__slots__ = ('args', 'kwargs')
|
|
||||||
def __init__(self, args=None, kwargs=None, **kwgs):
|
|
||||||
if args is None:
|
|
||||||
args = tuple()
|
|
||||||
if kwargs is None:
|
|
||||||
kwargs = {}
|
|
||||||
if kwgs:
|
|
||||||
kwargs.update(kwgs)
|
|
||||||
if isinstance(args, Param):
|
|
||||||
args = (args,)
|
|
||||||
else:
|
|
||||||
if not isinstance(args, tuple):
|
|
||||||
raise ValueError(_('args in params must be a tuple'))
|
|
||||||
for arg in args:
|
|
||||||
if not isinstance(arg, Param):
|
|
||||||
raise ValueError(_('arg in params must be a Param'))
|
|
||||||
if not isinstance(kwargs, dict):
|
|
||||||
raise ValueError(_('kwargs in params must be a dict'))
|
|
||||||
for arg in kwargs.values():
|
|
||||||
if not isinstance(arg, Param):
|
|
||||||
raise ValueError(_('arg in params must be a Param'))
|
|
||||||
self.args = args
|
|
||||||
self.kwargs = kwargs
|
|
||||||
|
|
||||||
|
|
||||||
class Param:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class ParamOption(Param):
|
|
||||||
__slots__ = ('option',
|
|
||||||
'notraisepropertyerror')
|
|
||||||
def __init__(self,
|
|
||||||
option: 'Option',
|
|
||||||
notraisepropertyerror: bool=False) -> None:
|
|
||||||
if __debug__ and not hasattr(option, 'impl_is_symlinkoption'):
|
|
||||||
raise ValueError(_('paramoption needs an option not {}').format(type(option)))
|
|
||||||
if option.impl_is_symlinkoption():
|
|
||||||
cur_opt = option.impl_getopt()
|
|
||||||
else:
|
|
||||||
cur_opt = option
|
|
||||||
if not isinstance(notraisepropertyerror, bool):
|
|
||||||
raise ValueError(_('param must have a boolean'
|
|
||||||
' not a {} for notraisepropertyerror'
|
|
||||||
).format(type(notraisepropertyerror)))
|
|
||||||
|
|
||||||
self.option = cur_opt
|
|
||||||
self.notraisepropertyerror = notraisepropertyerror
|
|
||||||
|
|
||||||
|
|
||||||
class ParamValue(Param):
|
|
||||||
__slots__ = ('value',)
|
|
||||||
def __init__(self, value):
|
|
||||||
self.value = value
|
|
||||||
|
|
||||||
|
|
||||||
class ParamContext(Param):
|
|
||||||
__slots__ = tuple()
|
|
||||||
|
|
||||||
|
|
||||||
class ParamIndex(Param):
|
|
||||||
__slots__ = tuple()
|
|
||||||
|
|
||||||
|
|
||||||
def tiramisu_copy(val): # pragma: no cover
|
def tiramisu_copy(val): # pragma: no cover
|
||||||
return val
|
return val
|
||||||
|
|
||||||
|
|
||||||
def calc_value(*args: List[Any],
|
class CalcValue:
|
||||||
multi: bool=False,
|
def __call__(self,
|
||||||
default: Any=undefined,
|
*args: List[Any],
|
||||||
condition: Any=undefined,
|
multi: bool=False,
|
||||||
expected: Any=undefined,
|
default: Any=undefined,
|
||||||
condition_operator: str='AND',
|
condition: Any=undefined,
|
||||||
allow_none: bool=False,
|
no_condition_is_invalid: Any=False,
|
||||||
remove_duplicate_value: bool=False,
|
expected: Any=undefined,
|
||||||
join: Optional[str]=None,
|
condition_operator: str='AND',
|
||||||
min_args_len: Optional[int]=None,
|
inverse_condition: bool=False,
|
||||||
operator: Optional[str]=None,
|
allow_none: bool=False,
|
||||||
index: Optional[int]=None,
|
remove_duplicate_value: bool=False,
|
||||||
**kwargs) -> Any:
|
join: Optional[str]=None,
|
||||||
"""calculate value
|
min_args_len: Optional[int]=None,
|
||||||
:param multi: value returns must be a list of value
|
operator: Optional[str]=None,
|
||||||
:param default: default value if condition is not matched or if args is empty
|
index: Optional[int]=None,
|
||||||
if there is more than one default value, set default_0, default_1, ...
|
**kwargs) -> Any:
|
||||||
:param condition: test if condition is equal to expected value
|
"""calculate value
|
||||||
if there is more than one condition, set condition_0, condition_1, ...
|
:param args: list of value
|
||||||
:param expected: value expected for all conditions
|
:param multi: value returns must be a list of value
|
||||||
if expected value is different between condition, set expected_0, expected_1, ...
|
:param default: default value if condition is not matched or if args is empty
|
||||||
:param condition_operator: OR or AND operator for condition
|
if there is more than one default value, set default_0, default_1, ...
|
||||||
:param allow_none: if False, do not return list in None is present in list
|
:param condition: test if condition is equal to expected value
|
||||||
:param remove_duplicate_value: if True, remote duplicated value
|
if there is more than one condition, set condition_0, condition_1, ...
|
||||||
:param join: join all args with specified characters
|
:param expected: value expected for all conditions
|
||||||
:param min_args_len: if number of arguments is smaller than this value, return default value
|
if expected value is different between condition, set expected_0, expected_1, ...
|
||||||
:param operator: operator
|
:param no_condition_is_invalid: if no condition and not condition_0, condition_1, ... (for
|
||||||
|
example if option is disabled) consider that condition not matching
|
||||||
|
:param condition_operator: OR or AND operator for condition
|
||||||
|
:param allow_none: if False, do not return list in None is present in list
|
||||||
|
:param remove_duplicate_value: if True, remote duplicated value
|
||||||
|
:param join: join all args with specified characters
|
||||||
|
:param min_args_len: if number of arguments is smaller than this value, return default value
|
||||||
|
:param operator: 'add', 'mul', 'div' or 'sub' all args (args must be integer value)
|
||||||
|
:param index: index for follower
|
||||||
|
|
||||||
examples:
|
examples:
|
||||||
* you want to copy value from an option to an other option:
|
* you want to copy value from an option to an other option:
|
||||||
>>> from tiramisu import calc_value, StrOption, OptionDescription, Config, Params, ParamOption
|
>>> from tiramisu import calc_value, StrOption, OptionDescription, Config, Params, ParamOption
|
||||||
>>> val1 = StrOption('val1', '', 'val1')
|
>>> val1 = StrOption('val1', '', 'val1')
|
||||||
>>> val2 = StrOption('val2', '', callback=calc_value, callback_params=Params(ParamOption(val1)))
|
>>> val2 = StrOption('val2', '', callback=calc_value, callback_params=Params(ParamOption(val1)))
|
||||||
>>> od = OptionDescription('root', '', [val1, val2])
|
>>> od = OptionDescription('root', '', [val1, val2])
|
||||||
>>> cfg = Config(od)
|
>>> cfg = Config(od)
|
||||||
>>> cfg.value.dict()
|
>>> cfg.value.dict()
|
||||||
{'val1': 'val1', 'val2': 'val1'}
|
{'val1': 'val1', 'val2': 'val1'}
|
||||||
|
|
||||||
* you want to copy values from two options in one multi option
|
* you want to copy values from two options in one multi option
|
||||||
>>> from tiramisu import calc_value, StrOption, OptionDescription, Config, Params, ParamOption, ParamValue
|
>>> from tiramisu import calc_value, StrOption, OptionDescription, Config, Params, ParamOption, ParamValue
|
||||||
>>> val1 = StrOption('val1', "", 'val1')
|
>>> val1 = StrOption('val1', "", 'val1')
|
||||||
>>> val2 = StrOption('val2', "", 'val2')
|
>>> val2 = StrOption('val2', "", 'val2')
|
||||||
>>> val3 = StrOption('val3', "", multi=True, callback=calc_value, callback_params=Params((ParamOption(val1), ParamOption(val2)), multi=ParamValue(True)))
|
>>> val3 = StrOption('val3', "", multi=True, callback=calc_value, callback_params=Params((ParamOption(val1), ParamOption(val2)), multi=ParamValue(True)))
|
||||||
>>> od = OptionDescription('root', '', [val1, val2, val3])
|
>>> od = OptionDescription('root', '', [val1, val2, val3])
|
||||||
>>> cfg = Config(od)
|
>>> cfg = Config(od)
|
||||||
>>> cfg.value.dict()
|
>>> cfg.value.dict()
|
||||||
{'val1': 'val1', 'val2': 'val2', 'val3': ['val1', 'val2']}
|
{'val1': 'val1', 'val2': 'val2', 'val3': ['val1', 'val2']}
|
||||||
|
|
||||||
* you want to copy a value from an option is it not disabled, otherwise set 'default_value'
|
* you want to copy a value from an option if it not disabled, otherwise set 'default_value'
|
||||||
>>> from tiramisu import calc_value, StrOption, OptionDescription, Config, Params, ParamOption, ParamValue
|
>>> from tiramisu import calc_value, StrOption, OptionDescription, Config, Params, ParamOption, ParamValue
|
||||||
>>> val1 = StrOption('val1', '', 'val1')
|
>>> val1 = StrOption('val1', '', 'val1')
|
||||||
>>> val2 = StrOption('val2', '', callback=calc_value, callback_params=Params(ParamOption(val1, True), default=ParamValue('default_value')))
|
>>> val2 = StrOption('val2', '', callback=calc_value, callback_params=Params(ParamOption(val1, True), default=ParamValue('default_value')))
|
||||||
>>> od = OptionDescription('root', '', [val1, val2])
|
>>> od = OptionDescription('root', '', [val1, val2])
|
||||||
>>> cfg = Config(od)
|
>>> cfg = Config(od)
|
||||||
>>> cfg.property.read_write()
|
>>> cfg.property.read_write()
|
||||||
>>> cfg.value.dict()
|
>>> cfg.value.dict()
|
||||||
{'val1': 'val1', 'val2': 'val1'}
|
{'val1': 'val1', 'val2': 'val1'}
|
||||||
>>> cfg.option('val1').property.add('disabled')
|
>>> cfg.option('val1').property.add('disabled')
|
||||||
>>> cfg.value.dict()
|
>>> cfg.value.dict()
|
||||||
{'val2': 'default_value'}
|
{'val2': 'default_value'}
|
||||||
|
|
||||||
* you want to copy value from an option is an other is True, otherwise set 'default_value'
|
* you want to copy value from an option if an other is True, otherwise set 'default_value'
|
||||||
>>> from tiramisu import calc_value, BoolOption, StrOption, OptionDescription, Config, Params, ParamOption, ParamValue
|
>>> from tiramisu import calc_value, BoolOption, StrOption, OptionDescription, Config, Params, ParamOption, ParamValue
|
||||||
>>> boolean = BoolOption('boolean', '', True)
|
>>> boolean = BoolOption('boolean', '', True)
|
||||||
>>> val1 = StrOption('val1', '', 'val1')
|
>>> val1 = StrOption('val1', '', 'val1')
|
||||||
>>> val2 = StrOption('val2', '', callback=calc_value, callback_params=Params(ParamOption(val1, True),
|
>>> val2 = StrOption('val2', '', callback=calc_value, callback_params=Params(ParamOption(val1, True),
|
||||||
... default=ParamValue('default_value'),
|
... default=ParamValue('default_value'),
|
||||||
... condition=ParamOption(boolean),
|
... condition=ParamOption(boolean),
|
||||||
... expected=ParamValue(True)))
|
... expected=ParamValue(True)))
|
||||||
>>> od = OptionDescription('root', '', [boolean, val1, val2])
|
>>> od = OptionDescription('root', '', [boolean, val1, val2])
|
||||||
>>> cfg = Config(od)
|
>>> cfg = Config(od)
|
||||||
>>> cfg.property.read_write()
|
>>> cfg.property.read_write()
|
||||||
>>> cfg.value.dict()
|
>>> cfg.value.dict()
|
||||||
{'boolean': True, 'val1': 'val1', 'val2': 'val1'}
|
{'boolean': True, 'val1': 'val1', 'val2': 'val1'}
|
||||||
>>> cfg.option('boolean').value.set(False)
|
>>> cfg.option('boolean').value.set(False)
|
||||||
>>> cfg.value.dict()
|
>>> cfg.value.dict()
|
||||||
{'boolean': False, 'val1': 'val1', 'val2': 'default_value'}
|
{'boolean': False, 'val1': 'val1', 'val2': 'default_value'}
|
||||||
|
|
||||||
* you want to copy option even if None is present
|
* you want to copy option even if None is present
|
||||||
>>> from tiramisu import calc_value, StrOption, OptionDescription, Config, Params, ParamOption, ParamValue
|
>>> from tiramisu import calc_value, StrOption, OptionDescription, Config, Params, ParamOption, ParamValue
|
||||||
>>> val1 = StrOption('val1', "", 'val1')
|
>>> val1 = StrOption('val1', "", 'val1')
|
||||||
>>> val2 = StrOption('val2', "")
|
>>> val2 = StrOption('val2', "")
|
||||||
>>> val3 = StrOption('val3', "", multi=True, callback=calc_value, callback_params=Params((ParamOption(val1), ParamOption(val2)), multi=ParamValue(True), allow_none=ParamValue(True)))
|
>>> val3 = StrOption('val3', "", multi=True, callback=calc_value, callback_params=Params((ParamOption(val1), ParamOption(val2)), multi=ParamValue(True), allow_none=ParamValue(True)))
|
||||||
>>> od = OptionDescription('root', '', [val1, val2, val3])
|
>>> od = OptionDescription('root', '', [val1, val2, val3])
|
||||||
>>> cfg = Config(od)
|
>>> cfg = Config(od)
|
||||||
>>> cfg.value.dict()
|
>>> cfg.value.dict()
|
||||||
{'val1': 'val1', 'val2': None, 'val3': ['val1', None]}
|
{'val1': 'val1', 'val2': None, 'val3': ['val1', None]}
|
||||||
|
|
||||||
* you want uniq value
|
* you want uniq value
|
||||||
>>> from tiramisu import calc_value, StrOption, OptionDescription, Config, Params, ParamOption, ParamValue
|
>>> from tiramisu import calc_value, StrOption, OptionDescription, Config, Params, ParamOption, ParamValue
|
||||||
>>> val1 = StrOption('val1', "", 'val1')
|
>>> val1 = StrOption('val1', "", 'val1')
|
||||||
>>> val2 = StrOption('val2', "", 'val1')
|
>>> val2 = StrOption('val2', "", 'val1')
|
||||||
>>> val3 = StrOption('val3', "", multi=True, callback=calc_value, callback_params=Params((ParamOption(val1), ParamOption(val2)), multi=ParamValue(True), remove_duplicate_value=ParamValue(True)))
|
>>> val3 = StrOption('val3', "", multi=True, callback=calc_value, callback_params=Params((ParamOption(val1), ParamOption(val2)), multi=ParamValue(True), remove_duplicate_value=ParamValue(True)))
|
||||||
>>> od = OptionDescription('root', '', [val1, val2, val3])
|
>>> od = OptionDescription('root', '', [val1, val2, val3])
|
||||||
>>> cfg = Config(od)
|
>>> cfg = Config(od)
|
||||||
>>> cfg.value.dict()
|
>>> cfg.value.dict()
|
||||||
{'val1': 'val1', 'val2': 'val1', 'val3': ['val1']}
|
{'val1': 'val1', 'val2': 'val1', 'val3': ['val1']}
|
||||||
|
|
||||||
* you want to join two values with '.'
|
* you want to join two values with '.'
|
||||||
>>> from tiramisu import calc_value, StrOption, OptionDescription, Config, Params, ParamOption, ParamValue
|
>>> from tiramisu import calc_value, StrOption, OptionDescription, Config, Params, ParamOption, ParamValue
|
||||||
>>> val1 = StrOption('val1', "", 'val1')
|
>>> val1 = StrOption('val1', "", 'val1')
|
||||||
>>> val2 = StrOption('val2', "", 'val2')
|
>>> val2 = StrOption('val2', "", 'val2')
|
||||||
>>> val3 = StrOption('val3', "", callback=calc_value, callback_params=Params((ParamOption(val1), ParamOption(val2)), join=ParamValue('.')))
|
>>> val3 = StrOption('val3', "", callback=calc_value, callback_params=Params((ParamOption(val1), ParamOption(val2)), join=ParamValue('.')))
|
||||||
>>> od = OptionDescription('root', '', [val1, val2, val3])
|
>>> od = OptionDescription('root', '', [val1, val2, val3])
|
||||||
>>> cfg = Config(od)
|
>>> cfg = Config(od)
|
||||||
>>> cfg.value.dict()
|
>>> cfg.value.dict()
|
||||||
{'val1': 'val1', 'val2': 'val2', 'val3': 'val1.val2'}
|
{'val1': 'val1', 'val2': 'val2', 'val3': 'val1.val2'}
|
||||||
|
|
||||||
* you want join three values, only if almost three values are set
|
* you want join three values, only if almost three values are set
|
||||||
>>> from tiramisu import calc_value, StrOption, OptionDescription, Config, Params, ParamOption, ParamValue
|
>>> from tiramisu import calc_value, StrOption, OptionDescription, Config, Params, ParamOption, ParamValue
|
||||||
>>> val1 = StrOption('val1', "", 'val1')
|
>>> val1 = StrOption('val1', "", 'val1')
|
||||||
>>> val2 = StrOption('val2', "", 'val2')
|
>>> val2 = StrOption('val2', "", 'val2')
|
||||||
>>> val3 = StrOption('val3', "", 'val3')
|
>>> val3 = StrOption('val3', "", 'val3')
|
||||||
>>> val4 = StrOption('val4', "", callback=calc_value, callback_params=Params((ParamOption(val1), ParamOption(val2), ParamOption(val3, True)), join=ParamValue('.'), min_args_len=ParamValue(3)))
|
>>> val4 = StrOption('val4', "", callback=calc_value, callback_params=Params((ParamOption(val1), ParamOption(val2), ParamOption(val3, True)), join=ParamValue('.'), min_args_len=ParamValue(3)))
|
||||||
>>> od = OptionDescription('root', '', [val1, val2, val3, val4])
|
>>> od = OptionDescription('root', '', [val1, val2, val3, val4])
|
||||||
>>> cfg = Config(od)
|
>>> cfg = Config(od)
|
||||||
>>> cfg.property.read_write()
|
>>> cfg.property.read_write()
|
||||||
>>> cfg.value.dict()
|
>>> cfg.value.dict()
|
||||||
{'val1': 'val1', 'val2': 'val2', 'val3': 'val3', 'val4': 'val1.val2.val3'}
|
{'val1': 'val1', 'val2': 'val2', 'val3': 'val3', 'val4': 'val1.val2.val3'}
|
||||||
>>> cfg.option('val3').property.add('disabled')
|
>>> cfg.option('val3').property.add('disabled')
|
||||||
>>> cfg.value.dict()
|
>>> cfg.value.dict()
|
||||||
{'val1': 'val1', 'val2': 'val2', 'val4': ''}
|
{'val1': 'val1', 'val2': 'val2', 'val4': ''}
|
||||||
|
|
||||||
* you want to add all values
|
* you want to add all values
|
||||||
>>> from tiramisu import calc_value, IntOption, OptionDescription, Config, Params, ParamOption, ParamValue
|
>>> from tiramisu import calc_value, IntOption, OptionDescription, Config, Params, ParamOption, ParamValue
|
||||||
>>> val1 = IntOption('val1', "", 1)
|
>>> val1 = IntOption('val1', "", 1)
|
||||||
>>> val2 = IntOption('val2', "", 2)
|
>>> val2 = IntOption('val2', "", 2)
|
||||||
>>> val3 = IntOption('val3', "", callback=calc_value, callback_params=Params((ParamOption(val1), ParamOption(val2)), operator=ParamValue('add')))
|
>>> val3 = IntOption('val3', "", callback=calc_value, callback_params=Params((ParamOption(val1), ParamOption(val2)), operator=ParamValue('add')))
|
||||||
>>> od = OptionDescription('root', '', [val1, val2, val3])
|
>>> od = OptionDescription('root', '', [val1, val2, val3])
|
||||||
>>> cfg = Config(od)
|
>>> cfg = Config(od)
|
||||||
>>> cfg.value.dict()
|
>>> cfg.value.dict()
|
||||||
{'val1': 1, 'val2': 2, 'val3': 3}
|
{'val1': 1, 'val2': 2, 'val3': 3}
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def value_from_kwargs(value: Any, pattern: str, to_dict: bool=False) -> Any:
|
self.args = args
|
||||||
|
self.condition = condition
|
||||||
|
self.expected = expected
|
||||||
|
self.condition_operator = condition_operator
|
||||||
|
self.inverse_condition = inverse_condition
|
||||||
|
self.kwargs = kwargs
|
||||||
|
self.no_condition_is_invalid = no_condition_is_invalid
|
||||||
|
value = self.get_value(default,
|
||||||
|
min_args_len)
|
||||||
|
if not multi:
|
||||||
|
if join is not None:
|
||||||
|
value = join.join(value)
|
||||||
|
elif value and operator:
|
||||||
|
new_value = value[0]
|
||||||
|
op = {'mul': mul,
|
||||||
|
'add': add,
|
||||||
|
'div': truediv,
|
||||||
|
'sub': sub}[operator]
|
||||||
|
for val in value[1:]:
|
||||||
|
new_value = op(new_value, val)
|
||||||
|
value = new_value
|
||||||
|
elif value == []:
|
||||||
|
value = None
|
||||||
|
else:
|
||||||
|
value = value[0]
|
||||||
|
if isinstance(value, list) and index is not None:
|
||||||
|
if len(value) > index:
|
||||||
|
value = value[index]
|
||||||
|
else:
|
||||||
|
value = None
|
||||||
|
elif None in value and not allow_none:
|
||||||
|
value = []
|
||||||
|
elif remove_duplicate_value:
|
||||||
|
new_value = []
|
||||||
|
for val in value:
|
||||||
|
if val not in new_value:
|
||||||
|
new_value.append(val)
|
||||||
|
value = new_value
|
||||||
|
return value
|
||||||
|
|
||||||
|
def value_from_kwargs(self,
|
||||||
|
value: Any,
|
||||||
|
pattern: str,
|
||||||
|
to_dict: bool=False,
|
||||||
|
empty_test=undefined) -> Any:
|
||||||
# if value attribute exist return it's value
|
# if value attribute exist return it's value
|
||||||
# otherwise pattern_0, pattern_1, ...
|
# otherwise pattern_0, pattern_1, ...
|
||||||
# otherwise undefined
|
# otherwise undefined
|
||||||
if value is not undefined:
|
if value is not empty_test:
|
||||||
if to_dict == 'all':
|
if to_dict == 'all':
|
||||||
returns = {0: value}
|
returns = {None: value}
|
||||||
else:
|
else:
|
||||||
returns = value
|
returns = value
|
||||||
else:
|
else:
|
||||||
kwargs_matches = {}
|
kwargs_matches = {}
|
||||||
len_pattern = len(pattern)
|
len_pattern = len(pattern)
|
||||||
for key in kwargs.keys():
|
for key in self.kwargs.keys():
|
||||||
if key.startswith(pattern):
|
if key.startswith(pattern):
|
||||||
index = int(key[len_pattern:])
|
index = int(key[len_pattern:])
|
||||||
kwargs_matches[index] = kwargs[key]
|
pattern_value = self.kwargs[key]
|
||||||
|
if isinstance(pattern_value, dict):
|
||||||
|
pattern_value = pattern_value['value']
|
||||||
|
kwargs_matches[index] = pattern_value
|
||||||
if not kwargs_matches:
|
if not kwargs_matches:
|
||||||
return undefined
|
returns = undefined
|
||||||
keys = sorted(kwargs_matches)
|
|
||||||
if to_dict:
|
|
||||||
returns = {}
|
|
||||||
else:
|
else:
|
||||||
returns = []
|
keys = sorted(kwargs_matches)
|
||||||
for key in keys:
|
|
||||||
if to_dict:
|
if to_dict:
|
||||||
returns[key] = kwargs_matches[key]
|
returns = {}
|
||||||
else:
|
else:
|
||||||
returns.append(kwargs_matches[key])
|
returns = []
|
||||||
|
for key in keys:
|
||||||
|
if to_dict:
|
||||||
|
returns[key] = kwargs_matches[key]
|
||||||
|
else:
|
||||||
|
returns.append(kwargs_matches[key])
|
||||||
return returns
|
return returns
|
||||||
|
|
||||||
def is_condition_matches():
|
def is_condition_matches(self,
|
||||||
calculated_conditions = value_from_kwargs(condition, 'condition_', to_dict='all')
|
condition_value):
|
||||||
if condition is not undefined:
|
calculated_conditions = self.value_from_kwargs(condition_value,
|
||||||
|
'condition_',
|
||||||
|
to_dict='all')
|
||||||
|
if calculated_conditions is undefined:
|
||||||
|
is_matches = not self.no_condition_is_invalid
|
||||||
|
else:
|
||||||
is_matches = None
|
is_matches = None
|
||||||
calculated_expected = value_from_kwargs(expected, 'expected_', to_dict=True)
|
calculated_expected = self.value_from_kwargs(self.expected,
|
||||||
|
'expected_',
|
||||||
|
to_dict=True)
|
||||||
|
calculated_inverse = self.value_from_kwargs(self.inverse_condition,
|
||||||
|
'inverse_condition_',
|
||||||
|
to_dict=True,
|
||||||
|
empty_test=False)
|
||||||
for idx, calculated_condition in calculated_conditions.items():
|
for idx, calculated_condition in calculated_conditions.items():
|
||||||
if isinstance(calculated_expected, dict):
|
if isinstance(calculated_expected, dict):
|
||||||
current_matches = calculated_condition == calculated_expected[idx]
|
if idx is not None:
|
||||||
|
current_matches = calculated_condition == calculated_expected[idx]
|
||||||
|
else:
|
||||||
|
current_matches = calculated_condition in calculated_expected.values()
|
||||||
else:
|
else:
|
||||||
current_matches = calculated_condition == calculated_expected
|
current_matches = calculated_condition == calculated_expected
|
||||||
|
if isinstance(calculated_inverse, dict) and idx in calculated_inverse:
|
||||||
|
inverse_condition = calculated_inverse[idx]
|
||||||
|
else:
|
||||||
|
inverse_condition = False
|
||||||
if is_matches is None:
|
if is_matches is None:
|
||||||
is_matches = current_matches
|
is_matches = current_matches
|
||||||
elif condition_operator == 'AND':
|
if self.condition_operator == 'AND':
|
||||||
is_matches = is_matches and current_matches
|
is_matches = is_matches and current_matches
|
||||||
elif condition_operator == 'OR':
|
if inverse_condition:
|
||||||
|
is_matches = not is_matches
|
||||||
|
if not is_matches:
|
||||||
|
break
|
||||||
|
elif self.condition_operator == 'OR':
|
||||||
is_matches = is_matches or current_matches
|
is_matches = is_matches or current_matches
|
||||||
|
if inverse_condition:
|
||||||
|
is_matches = not is_matches
|
||||||
|
if is_matches:
|
||||||
|
break
|
||||||
else:
|
else:
|
||||||
raise ValueError(_('unexpected {} condition_operator in calc_value').format(condition_operator))
|
raise ValueError(_('unexpected {} condition_operator in calc_value').format(self.condition_operator))
|
||||||
else:
|
is_matches = is_matches and not self.inverse_condition \
|
||||||
is_matches = True
|
or not is_matches and self.inverse_condition
|
||||||
return is_matches
|
return is_matches
|
||||||
|
|
||||||
def get_value():
|
def get_value(self,
|
||||||
if not is_condition_matches():
|
default,
|
||||||
|
min_args_len):
|
||||||
|
if isinstance(self.condition, dict):
|
||||||
|
if 'value' in self.condition:
|
||||||
|
condition_value = self.condition['value']
|
||||||
|
else:
|
||||||
|
condition_value = undefined
|
||||||
|
else:
|
||||||
|
condition_value = self.condition
|
||||||
|
condition_matches = self.is_condition_matches(condition_value)
|
||||||
|
if not condition_matches:
|
||||||
# force to default
|
# force to default
|
||||||
value = []
|
value = []
|
||||||
else:
|
else:
|
||||||
value = list(args)
|
value = self.get_args()
|
||||||
if min_args_len and not len(value) >= min_args_len:
|
if min_args_len and not len(value) >= min_args_len:
|
||||||
value = []
|
value = []
|
||||||
if value == []:
|
if value == []:
|
||||||
# default value
|
# default value
|
||||||
new_default = value_from_kwargs(default, 'default_')
|
new_default = self.value_from_kwargs(default,
|
||||||
|
'default_')
|
||||||
if new_default is not undefined:
|
if new_default is not undefined:
|
||||||
if not isinstance(new_default, list):
|
if not isinstance(new_default, list):
|
||||||
value = [new_default]
|
value = [new_default]
|
||||||
|
@ -291,34 +320,72 @@ def calc_value(*args: List[Any],
|
||||||
value = new_default
|
value = new_default
|
||||||
return value
|
return value
|
||||||
|
|
||||||
value = get_value()
|
def get_args(self):
|
||||||
if not multi:
|
return list(self.args)
|
||||||
if join is not None:
|
|
||||||
value = join.join(value)
|
|
||||||
elif value and operator:
|
class CalcValuePropertyHelp(CalcValue):
|
||||||
new_value = value[0]
|
def get_name(self):
|
||||||
op = {'mul': mul,
|
return self.condition['name']
|
||||||
'add': add,
|
|
||||||
'div': truediv,
|
def get_indexed_name(self, index):
|
||||||
'sub': sub}[operator]
|
return self.kwargs.get(f'condition_{index}')['name']
|
||||||
for val in value[1:]:
|
|
||||||
new_value = op(new_value, val)
|
def has_condition_kwargs(self):
|
||||||
value = new_value
|
for condition in self.kwargs:
|
||||||
elif value == []:
|
if condition.startswith('condition_'):
|
||||||
value = None
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def build_arg(self, name, value):
|
||||||
|
#if isinstance(option, tuple):
|
||||||
|
# if not inverse:
|
||||||
|
# msg = _('the calculated value is {0}').format(display_value)
|
||||||
|
# else:
|
||||||
|
# msg = _('the calculated value is not {0}').format(display_value)
|
||||||
|
#else:
|
||||||
|
if not self.inverse_condition:
|
||||||
|
msg = _('the value of "{0}" is {1}').format(name, value)
|
||||||
else:
|
else:
|
||||||
value = value[0]
|
msg = _('the value of "{0}" is not {1}').format(name, value)
|
||||||
if isinstance(value, list) and index is not None:
|
return msg
|
||||||
if len(value) > index:
|
|
||||||
value = value[index]
|
def get_args(self):
|
||||||
|
args = super().get_args()
|
||||||
|
if args:
|
||||||
|
if len(self.args) != 1:
|
||||||
|
raise ValueError(_('only one property is allowed for a calculation'))
|
||||||
|
action = args[0]
|
||||||
|
calculated_expected = self.value_from_kwargs(self.expected,
|
||||||
|
'expected_',
|
||||||
|
to_dict=True)
|
||||||
|
if self.condition is not undefined:
|
||||||
|
if 'propertyerror' in self.condition:
|
||||||
|
msg = self.condition['propertyerror']
|
||||||
else:
|
else:
|
||||||
value = None
|
name = self.get_name()
|
||||||
elif None in value and not allow_none:
|
if isinstance(calculated_expected, dict):
|
||||||
value = []
|
calc_values = calculated_expected.values()
|
||||||
elif remove_duplicate_value:
|
else:
|
||||||
new_value = []
|
calc_values = [calculated_expected]
|
||||||
for val in value:
|
display_value = display_list([str(val) for val in calc_values],
|
||||||
if val not in new_value:
|
'or',
|
||||||
new_value.append(val)
|
add_quote=True)
|
||||||
value = new_value
|
msg = self.build_arg(name, display_value)
|
||||||
return value
|
elif self.has_condition_kwargs():
|
||||||
|
msgs = []
|
||||||
|
for key, value in calculated_expected.items():
|
||||||
|
name = self.get_indexed_name(key)
|
||||||
|
msgs.append(self.build_arg(name, f'"{value}"'))
|
||||||
|
msg = display_list(msgs, self.condition_operator.lower())
|
||||||
|
else:
|
||||||
|
return [f'"{action}"']
|
||||||
|
return [f'"{action}" ({msg})']
|
||||||
|
return
|
||||||
|
## calc_properties.setdefault(action, []).append(msg)
|
||||||
|
|
||||||
|
|
||||||
|
calc_value = CalcValue()
|
||||||
|
calc_value.__name__ = 'calc_value'
|
||||||
|
calc_value_property_help = CalcValuePropertyHelp()
|
||||||
|
calc_value_property_help.__name__ = 'calc_value_property_help'
|
||||||
|
|
|
@ -29,7 +29,7 @@ from ..i18n import _
|
||||||
from ..setting import undefined, Settings
|
from ..setting import undefined, Settings
|
||||||
from ..value import Values
|
from ..value import Values
|
||||||
from ..error import ConfigError, display_list
|
from ..error import ConfigError, display_list
|
||||||
from ..function import Params, ParamContext, ParamOption, ParamIndex
|
from ..autolib import Calculation, Params, ParamContext, ParamOption, ParamIndex
|
||||||
|
|
||||||
STATIC_TUPLE = frozenset()
|
STATIC_TUPLE = frozenset()
|
||||||
|
|
||||||
|
@ -83,16 +83,15 @@ class Base:
|
||||||
requires = undefined
|
requires = undefined
|
||||||
if properties is None:
|
if properties is None:
|
||||||
properties = frozenset()
|
properties = frozenset()
|
||||||
if isinstance(properties, tuple):
|
elif isinstance(properties, tuple):
|
||||||
properties = frozenset(properties)
|
properties = frozenset(properties)
|
||||||
if is_multi and 'empty' not in properties:
|
if is_multi and 'empty' not in properties:
|
||||||
# if option is a multi, it cannot be "empty" (None not allowed in the list)
|
# if option is a multi, it cannot be "empty" (None not allowed in the list)
|
||||||
# "empty" is removed for follower's option
|
# "empty" is removed for follower's option
|
||||||
properties = properties | {'empty'}
|
properties = properties | {'empty'}
|
||||||
if not isinstance(properties, frozenset):
|
assert isinstance(properties, frozenset), _('invalid properties type {0} for {1},'
|
||||||
raise TypeError(_('invalid properties type {0} for {1},'
|
' must be a frozenset').format(type(properties),
|
||||||
' must be a frozenset').format(type(properties),
|
name)
|
||||||
name))
|
|
||||||
self.validate_properties(name,
|
self.validate_properties(name,
|
||||||
calc_properties,
|
calc_properties,
|
||||||
properties)
|
properties)
|
||||||
|
@ -115,6 +114,17 @@ class Base:
|
||||||
raise ValueError(_('conflict: properties already set in requirement {0} for {1}'
|
raise ValueError(_('conflict: properties already set in requirement {0} for {1}'
|
||||||
'').format(display_list(set_forbidden_properties, add_quote=True),
|
'').format(display_list(set_forbidden_properties, add_quote=True),
|
||||||
name))
|
name))
|
||||||
|
assert isinstance(properties, frozenset), _('invalid properties type {0} for {1},'
|
||||||
|
' must be a frozenset').format(type(properties),
|
||||||
|
name)
|
||||||
|
for prop in properties:
|
||||||
|
if not isinstance(prop, str):
|
||||||
|
if not isinstance(prop, Calculation):
|
||||||
|
raise ValueError(_('invalid property type {0} for {1}, must be a string or a Calculation').format(type(prop), name))
|
||||||
|
params = prop.params
|
||||||
|
for param in chain(params.args, params.kwargs.values()):
|
||||||
|
if isinstance(param, ParamOption):
|
||||||
|
param.option._add_dependency(self)
|
||||||
|
|
||||||
def _get_function_args(self,
|
def _get_function_args(self,
|
||||||
function: Callable) -> Tuple[Set[str], Set[str], bool, bool]:
|
function: Callable) -> Tuple[Set[str], Set[str], bool, bool]:
|
||||||
|
@ -159,7 +169,7 @@ class Base:
|
||||||
"""
|
"""
|
||||||
:add_value: add value as first argument for validator
|
:add_value: add value as first argument for validator
|
||||||
"""
|
"""
|
||||||
assert isinstance(calculator, FunctionType), _('{0} must be a function').format(type_)
|
assert isinstance(calculator, Callable), _('{0} must be a function').format(type_)
|
||||||
if calculator_params is not None:
|
if calculator_params is not None:
|
||||||
assert isinstance(calculator_params, Params), _('{0}_params must be a params'
|
assert isinstance(calculator_params, Params), _('{0}_params must be a params'
|
||||||
'').format(type_)
|
'').format(type_)
|
||||||
|
|
|
@ -32,7 +32,7 @@ from .syndynoptiondescription import SynDynLeadership
|
||||||
from .baseoption import BaseOption
|
from .baseoption import BaseOption
|
||||||
from .option import Option
|
from .option import Option
|
||||||
from ..error import RequirementError
|
from ..error import RequirementError
|
||||||
from ..function import ParamOption
|
from ..autolib import ParamOption
|
||||||
|
|
||||||
|
|
||||||
class Leadership(OptionDescription):
|
class Leadership(OptionDescription):
|
||||||
|
@ -97,11 +97,8 @@ class Leadership(OptionDescription):
|
||||||
raise RequirementError(_('leader {} have requirement, but Leadership {} too'
|
raise RequirementError(_('leader {} have requirement, but Leadership {} too'
|
||||||
'').format(leader.impl_getname(),
|
'').format(leader.impl_getname(),
|
||||||
self.impl_getname()))
|
self.impl_getname()))
|
||||||
leader_calproperties = getattr(leader, '_calc_properties', None)
|
leader_calproperties = getattr(leader, '_requires', None)
|
||||||
if leader_calproperties:
|
if leader_calproperties:
|
||||||
if __debug__ and properties is not None:
|
|
||||||
self.validate_properties(name, leader_calproperties, frozenset(properties))
|
|
||||||
setattr(self, '_calc_properties', leader_calproperties)
|
|
||||||
setattr(self, '_requires', leader_requires)
|
setattr(self, '_requires', leader_requires)
|
||||||
delattr(leader, '_requires')
|
delattr(leader, '_requires')
|
||||||
if __debug__:
|
if __debug__:
|
||||||
|
|
|
@ -26,10 +26,9 @@ from typing import Any, List, Callable, Optional, Dict, Union, Tuple
|
||||||
from .baseoption import BaseOption, submulti, STATIC_TUPLE
|
from .baseoption import BaseOption, submulti, STATIC_TUPLE
|
||||||
from ..i18n import _
|
from ..i18n import _
|
||||||
from ..setting import undefined, OptionBag, Undefined
|
from ..setting import undefined, OptionBag, Undefined
|
||||||
from ..autolib import carry_out_calculation
|
from ..autolib import carry_out_calculation, Params, ParamValue
|
||||||
from ..error import (ConfigError, ValueWarning, ValueErrorWarning, PropertiesOptionError,
|
from ..error import (ConfigError, ValueWarning, ValueErrorWarning, PropertiesOptionError,
|
||||||
ValueOptionError, display_list)
|
ValueOptionError, display_list)
|
||||||
from ..function import Params, ParamValue
|
|
||||||
from .syndynoption import SynDynOption
|
from .syndynoption import SynDynOption
|
||||||
ALLOWED_CONST_LIST = ['_cons_not_equal']
|
ALLOWED_CONST_LIST = ['_cons_not_equal']
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,9 @@ class SynDynOptionDescription:
|
||||||
subpath: str,
|
subpath: str,
|
||||||
suffix: str) -> None:
|
suffix: str) -> None:
|
||||||
self._opt = opt
|
self._opt = opt
|
||||||
|
if subpath is None:
|
||||||
|
subpath = ''
|
||||||
|
assert isinstance(subpath, str), 'subpath must be a string, not {}'.format(type(subpath))
|
||||||
self._subpath = subpath
|
self._subpath = subpath
|
||||||
self._suffix = suffix
|
self._suffix = suffix
|
||||||
|
|
||||||
|
|
|
@ -415,13 +415,13 @@ class Settings(object):
|
||||||
search_properties=None):
|
search_properties=None):
|
||||||
"""
|
"""
|
||||||
"""
|
"""
|
||||||
opt = option_bag.option
|
# FIXME search_properties
|
||||||
|
option = option_bag.option
|
||||||
config_bag = option_bag.config_bag
|
config_bag = option_bag.config_bag
|
||||||
path = option_bag.path
|
if option.impl_is_symlinkoption():
|
||||||
|
option = option.impl_getopt()
|
||||||
|
path = option.impl_getpath()
|
||||||
index = option_bag.index
|
index = option_bag.index
|
||||||
if opt.impl_is_symlinkoption():
|
|
||||||
opt = opt.impl_getopt()
|
|
||||||
path = opt.impl_getpath()
|
|
||||||
|
|
||||||
if apply_requires:
|
if apply_requires:
|
||||||
cache = config_bag.context._impl_properties_cache
|
cache = config_bag.context._impl_properties_cache
|
||||||
|
@ -435,13 +435,28 @@ class Settings(object):
|
||||||
else:
|
else:
|
||||||
is_cached = False
|
is_cached = False
|
||||||
if not is_cached:
|
if not is_cached:
|
||||||
props = self._p_.getproperties(path,
|
props = set()
|
||||||
opt.impl_getproperties())
|
for prop in self._p_.getproperties(path,
|
||||||
|
option.impl_getproperties()):
|
||||||
|
if isinstance(prop, str):
|
||||||
|
props.add(prop)
|
||||||
|
elif apply_requires:
|
||||||
|
new_props = prop.execute(option_bag,
|
||||||
|
leadership_must_have_index=True)
|
||||||
|
if not new_props:
|
||||||
|
continue
|
||||||
|
elif not isinstance(new_props, str):
|
||||||
|
raise ValueError(_('invalid property type {} for {} with {} function').format(type(new_props),
|
||||||
|
option_bag.option.impl_getname(),
|
||||||
|
prop.function.__name__))
|
||||||
|
props.add(new_props)
|
||||||
|
# else:
|
||||||
|
# props.update(new_props)
|
||||||
if apply_requires:
|
if apply_requires:
|
||||||
props |= self.apply_requires(option_bag,
|
props |= self.apply_requires(option_bag,
|
||||||
False,
|
False,
|
||||||
search_properties=search_properties)
|
search_properties=search_properties)
|
||||||
props -= self.getpermissives(opt,
|
props -= self.getpermissives(option,
|
||||||
path)
|
path)
|
||||||
#if apply_requires and config_bag.properties == config_bag.true_properties:
|
#if apply_requires and config_bag.properties == config_bag.true_properties:
|
||||||
if apply_requires and not config_bag.is_unrestraint:
|
if apply_requires and not config_bag.is_unrestraint:
|
||||||
|
@ -453,6 +468,29 @@ class Settings(object):
|
||||||
True)
|
True)
|
||||||
return props
|
return props
|
||||||
|
|
||||||
|
def get_calculated_properties(self,
|
||||||
|
option_bag):
|
||||||
|
opt = option_bag.option
|
||||||
|
if opt.impl_is_symlinkoption():
|
||||||
|
opt = opt.impl_getopt()
|
||||||
|
path = opt.impl_getpath()
|
||||||
|
for prop in self._p_.getproperties(path,
|
||||||
|
opt.impl_getproperties()):
|
||||||
|
if not isinstance(prop, str):
|
||||||
|
yield prop
|
||||||
|
|
||||||
|
def has_properties_index(self,
|
||||||
|
option_bag):
|
||||||
|
opt = option_bag.option
|
||||||
|
if opt.impl_is_symlinkoption():
|
||||||
|
opt = opt.impl_getopt()
|
||||||
|
path = opt.impl_getpath()
|
||||||
|
for prop in self._p_.getproperties(path,
|
||||||
|
opt.impl_getproperties()):
|
||||||
|
if not isinstance(prop, str) and prop.has_index:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def get_context_permissives(self):
|
def get_context_permissives(self):
|
||||||
return self.getpermissives(None, None)
|
return self.getpermissives(None, None)
|
||||||
|
|
||||||
|
@ -670,7 +708,6 @@ class Settings(object):
|
||||||
"""save properties for specified path
|
"""save properties for specified path
|
||||||
(never save properties if same has option properties)
|
(never save properties if same has option properties)
|
||||||
"""
|
"""
|
||||||
# should have index !!!
|
|
||||||
opt = option_bag.option
|
opt = option_bag.option
|
||||||
if opt.impl_getrequires() is not None:
|
if opt.impl_getrequires() is not None:
|
||||||
not_allowed_props = properties & \
|
not_allowed_props = properties & \
|
||||||
|
|
|
@ -31,7 +31,7 @@ from os.path import split
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
from ..error import ConfigError
|
from ..error import ConfigError
|
||||||
from ..i18n import _
|
from ..i18n import _
|
||||||
from .util import Cache
|
from .cacheobj import Cache
|
||||||
|
|
||||||
|
|
||||||
DEFAULT_STORAGE = MEMORY_STORAGE = 'dictionary'
|
DEFAULT_STORAGE = MEMORY_STORAGE = 'dictionary'
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"utils used by storage"
|
"cache used by storage"
|
||||||
# Copyright (C) 2013-2019 Team tiramisu (see AUTHORS for all contributors)
|
# Copyright (C) 2013-2019 Team tiramisu (see AUTHORS for all contributors)
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify it
|
# This program is free software: you can redistribute it and/or modify it
|
|
@ -15,10 +15,11 @@
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
# ____________________________________________________________
|
# ____________________________________________________________
|
||||||
|
import sqlite3
|
||||||
|
import warnings
|
||||||
|
|
||||||
from ...i18n import _
|
from ...i18n import _
|
||||||
from os.path import join
|
from os.path import join
|
||||||
import sqlite3
|
|
||||||
from ...error import ConflictError
|
from ...error import ConflictError
|
||||||
|
|
||||||
|
|
||||||
|
@ -55,9 +56,16 @@ def _gen_filename():
|
||||||
|
|
||||||
|
|
||||||
def list_sessions():
|
def list_sessions():
|
||||||
cursor = CONN.cursor()
|
if not CONN:
|
||||||
names = [row[0] for row in cursor.execute("SELECT session FROM session").fetchall()]
|
warnings.warn_explicit(Warning(_('Cannot list sessions, please connect to database first')),
|
||||||
return names
|
category=Warning,
|
||||||
|
filename=__file__,
|
||||||
|
lineno=63)
|
||||||
|
return []
|
||||||
|
else:
|
||||||
|
cursor = CONN.cursor()
|
||||||
|
names = [row[0] for row in cursor.execute("SELECT session FROM session").fetchall()]
|
||||||
|
return names
|
||||||
|
|
||||||
|
|
||||||
def delete_session(session_id,
|
def delete_session(session_id,
|
||||||
|
|
|
@ -19,8 +19,7 @@ import weakref
|
||||||
from typing import Optional, Any, Callable
|
from typing import Optional, Any, Callable
|
||||||
from .error import ConfigError, PropertiesOptionError, RequirementError
|
from .error import ConfigError, PropertiesOptionError, RequirementError
|
||||||
from .setting import owners, undefined, forbidden_owners, OptionBag, ConfigBag
|
from .setting import owners, undefined, forbidden_owners, OptionBag, ConfigBag
|
||||||
from .autolib import carry_out_calculation
|
from .autolib import carry_out_calculation, Params
|
||||||
from .function import Params
|
|
||||||
from .i18n import _
|
from .i18n import _
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue