Compare commits
3 Commits
release/3.
...
release/3.
Author | SHA1 | Date | |
---|---|---|---|
05abe76932 | |||
33c1666cc9 | |||
2a6df8c8d8 |
@ -4,8 +4,7 @@ do_autopath()
|
|||||||
import warnings, sys
|
import warnings, sys
|
||||||
from py.test import raises
|
from py.test import raises
|
||||||
|
|
||||||
from tiramisu import Config
|
from tiramisu import Config, DomainnameOption, EmailOption, URLOption, OptionDescription
|
||||||
from tiramisu.option import DomainnameOption, EmailOption, URLOption, OptionDescription
|
|
||||||
from tiramisu.error import ValueWarning
|
from tiramisu.error import ValueWarning
|
||||||
from tiramisu.i18n import _
|
from tiramisu.i18n import _
|
||||||
from tiramisu.storage import list_sessions
|
from tiramisu.storage import list_sessions
|
||||||
@ -19,9 +18,11 @@ def test_domainname():
|
|||||||
d = DomainnameOption('d', '')
|
d = DomainnameOption('d', '')
|
||||||
f = DomainnameOption('f', '', allow_without_dot=True)
|
f = DomainnameOption('f', '', allow_without_dot=True)
|
||||||
g = DomainnameOption('g', '', allow_ip=True)
|
g = DomainnameOption('g', '', allow_ip=True)
|
||||||
od = OptionDescription('a', '', [d, f, g])
|
h = DomainnameOption('h', '', allow_ip=True, cidr=True)
|
||||||
|
od = OptionDescription('a', '', [d, f, g, h])
|
||||||
cfg = Config(od)
|
cfg = Config(od)
|
||||||
cfg.property.read_write()
|
cfg.property.read_write()
|
||||||
|
#
|
||||||
cfg.option('d').value.set('toto.com')
|
cfg.option('d').value.set('toto.com')
|
||||||
raises(ValueError, "cfg.option('d').value.set('toto')")
|
raises(ValueError, "cfg.option('d').value.set('toto')")
|
||||||
cfg.option('d').value.set('toto3.com')
|
cfg.option('d').value.set('toto3.com')
|
||||||
@ -40,9 +41,17 @@ def test_domainname():
|
|||||||
cfg.option('f').value.set('d.t')
|
cfg.option('f').value.set('d.t')
|
||||||
#
|
#
|
||||||
raises(ValueError, "cfg.option('f').value.set('192.168.1.1')")
|
raises(ValueError, "cfg.option('f').value.set('192.168.1.1')")
|
||||||
|
raises(ValueError, "cfg.option('f').value.set('192.168.1.0/24')")
|
||||||
|
#
|
||||||
cfg.option('g').value.set('toto.com')
|
cfg.option('g').value.set('toto.com')
|
||||||
cfg.option('g').value.set('192.168.1.0')
|
cfg.option('g').value.set('192.168.1.0')
|
||||||
cfg.option('g').value.set('192.168.1.29')
|
cfg.option('g').value.set('192.168.1.29')
|
||||||
|
raises(ValueError, "cfg.option('g').value.set('192.168.1.0/24')")
|
||||||
|
#
|
||||||
|
cfg.option('h').value.set('toto.com')
|
||||||
|
raises(ValueError, "cfg.option('h').value.set('192.168.1.0')")
|
||||||
|
raises(ValueError, "cfg.option('h').value.set('192.168.1.29')")
|
||||||
|
cfg.option('h').value.set('192.168.1.0/24')
|
||||||
|
|
||||||
|
|
||||||
def test_domainname_upper():
|
def test_domainname_upper():
|
||||||
|
@ -8,7 +8,7 @@ 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
|
undefined, Params, ParamOption, ParamValue, ParamContext, calc_value
|
||||||
from tiramisu.api import TIRAMISU_VERSION
|
from tiramisu.api import TIRAMISU_VERSION
|
||||||
from tiramisu.error import PropertiesOptionError, ConflictError, LeadershipError, ConfigError
|
from tiramisu.error import PropertiesOptionError, ConflictError, LeadershipError, ConfigError
|
||||||
from tiramisu.i18n import _
|
from tiramisu.i18n import _
|
||||||
@ -1194,3 +1194,100 @@ def test_callback_raise():
|
|||||||
api.option('od2.opt2').value.get()
|
api.option('od2.opt2').value.get()
|
||||||
except ConfigError as err:
|
except ConfigError as err:
|
||||||
assert '"Option 2"' in str(err)
|
assert '"Option 2"' in str(err)
|
||||||
|
|
||||||
|
|
||||||
|
def test_calc_value_simple():
|
||||||
|
val1 = StrOption('val1', '', 'val1')
|
||||||
|
val2 = StrOption('val2', '', callback=calc_value, callback_params=Params(ParamOption(val1)))
|
||||||
|
od = OptionDescription('root', '', [val1, val2])
|
||||||
|
cfg = Config(od)
|
||||||
|
assert cfg.value.dict() == {'val1': 'val1', 'val2': 'val1'}
|
||||||
|
|
||||||
|
|
||||||
|
def test_calc_value_multi():
|
||||||
|
val1 = StrOption('val1', "", 'val1')
|
||||||
|
val2 = StrOption('val2', "", 'val2')
|
||||||
|
val3 = StrOption('val3', "", multi=True, callback=calc_value, callback_params=Params((ParamOption(val1), ParamOption(val2)), multi=ParamValue(True)))
|
||||||
|
od = OptionDescription('root', '', [val1, val2, val3])
|
||||||
|
cfg = Config(od)
|
||||||
|
assert cfg.value.dict() == {'val1': 'val1', 'val2': 'val2', 'val3': ['val1', 'val2']}
|
||||||
|
|
||||||
|
|
||||||
|
def test_calc_value_disabled():
|
||||||
|
val1 = StrOption('val1', '', 'val1')
|
||||||
|
val2 = StrOption('val2', '', callback=calc_value, callback_params=Params(ParamOption(val1, True), default=ParamValue('default_value')))
|
||||||
|
od = OptionDescription('root', '', [val1, val2])
|
||||||
|
cfg = Config(od)
|
||||||
|
cfg.property.read_write()
|
||||||
|
assert cfg.value.dict() == {'val1': 'val1', 'val2': 'val1'}
|
||||||
|
cfg.option('val1').property.add('disabled')
|
||||||
|
assert cfg.value.dict() == {'val2': 'default_value'}
|
||||||
|
|
||||||
|
|
||||||
|
def test_calc_value_condition():
|
||||||
|
boolean = BoolOption('boolean', '', True)
|
||||||
|
val1 = StrOption('val1', '', 'val1')
|
||||||
|
val2 = StrOption('val2', '', callback=calc_value, callback_params=Params(ParamOption(val1, True),
|
||||||
|
default=ParamValue('default_value'),
|
||||||
|
condition=ParamOption(boolean),
|
||||||
|
expected=ParamValue(True)))
|
||||||
|
od = OptionDescription('root', '', [boolean, val1, val2])
|
||||||
|
cfg = Config(od)
|
||||||
|
cfg.property.read_write()
|
||||||
|
assert cfg.value.dict() == {'boolean': True, 'val1': 'val1', 'val2': 'val1'}
|
||||||
|
cfg.option('boolean').value.set(False)
|
||||||
|
assert cfg.value.dict() == {'boolean': False, 'val1': 'val1', 'val2': 'default_value'}
|
||||||
|
|
||||||
|
|
||||||
|
def test_calc_value_allow_none():
|
||||||
|
from tiramisu import calc_value, StrOption, OptionDescription, Config, Params, ParamOption, ParamValue
|
||||||
|
val1 = StrOption('val1', "", 'val1')
|
||||||
|
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)))
|
||||||
|
od = OptionDescription('root', '', [val1, val2, val3])
|
||||||
|
cfg = Config(od)
|
||||||
|
assert cfg.value.dict() == {'val1': 'val1', 'val2': None, 'val3': ['val1', None]}
|
||||||
|
|
||||||
|
|
||||||
|
def test_calc_value_remove_duplicate():
|
||||||
|
from tiramisu import calc_value, StrOption, OptionDescription, Config, Params, ParamOption, ParamValue
|
||||||
|
val1 = StrOption('val1', "", '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)))
|
||||||
|
od = OptionDescription('root', '', [val1, val2, val3])
|
||||||
|
cfg = Config(od)
|
||||||
|
assert cfg.value.dict() == {'val1': 'val1', 'val2': 'val1', 'val3': ['val1']}
|
||||||
|
|
||||||
|
|
||||||
|
def test_calc_value_join():
|
||||||
|
from tiramisu import calc_value, StrOption, OptionDescription, Config, Params, ParamOption, ParamValue
|
||||||
|
val1 = StrOption('val1', "", 'val1')
|
||||||
|
val2 = StrOption('val2', "", 'val2')
|
||||||
|
val3 = StrOption('val3', "", callback=calc_value, callback_params=Params((ParamOption(val1), ParamOption(val2)), join=ParamValue('.')))
|
||||||
|
od = OptionDescription('root', '', [val1, val2, val3])
|
||||||
|
cfg = Config(od)
|
||||||
|
assert cfg.value.dict() == {'val1': 'val1', 'val2': 'val2', 'val3': 'val1.val2'}
|
||||||
|
|
||||||
|
|
||||||
|
def test_calc_value_min():
|
||||||
|
from tiramisu import calc_value, StrOption, OptionDescription, Config, Params, ParamOption, ParamValue
|
||||||
|
val1 = StrOption('val1', "", 'val1')
|
||||||
|
val2 = StrOption('val2', "", 'val2')
|
||||||
|
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)))
|
||||||
|
od = OptionDescription('root', '', [val1, val2, val3, val4])
|
||||||
|
cfg = Config(od)
|
||||||
|
cfg.property.read_write()
|
||||||
|
assert cfg.value.dict() == {'val1': 'val1', 'val2': 'val2', 'val3': 'val3', 'val4': 'val1.val2.val3'}
|
||||||
|
cfg.option('val3').property.add('disabled')
|
||||||
|
assert cfg.value.dict() == {'val1': 'val1', 'val2': 'val2', 'val4': ''}
|
||||||
|
|
||||||
|
|
||||||
|
def test_calc_value_add():
|
||||||
|
from tiramisu import calc_value, IntOption, OptionDescription, Config, Params, ParamOption, ParamValue
|
||||||
|
val1 = IntOption('val1', "", 1)
|
||||||
|
val2 = IntOption('val2', "", 2)
|
||||||
|
val3 = IntOption('val3', "", callback=calc_value, callback_params=Params((ParamOption(val1), ParamOption(val2)), operator=ParamValue('add')))
|
||||||
|
od = OptionDescription('root', '', [val1, val2, val3])
|
||||||
|
cfg = Config(od)
|
||||||
|
assert cfg.value.dict() == {'val1': 1, 'val2': 2, 'val3': 3}
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
from .function import Params, ParamOption, ParamValue, ParamContext, \
|
from .function import Params, ParamOption, ParamValue, ParamContext, \
|
||||||
tiramisu_copy
|
tiramisu_copy, calc_value
|
||||||
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
|
||||||
@ -37,7 +37,8 @@ allfuncs = ['Params',
|
|||||||
'Storage',
|
'Storage',
|
||||||
'list_sessions',
|
'list_sessions',
|
||||||
'delete_session',
|
'delete_session',
|
||||||
'tiramisu_copy']
|
'tiramisu_copy',
|
||||||
|
'calc_value']
|
||||||
allfuncs.extend(all_options)
|
allfuncs.extend(all_options)
|
||||||
del(all_options)
|
del(all_options)
|
||||||
__all__ = tuple(allfuncs)
|
__all__ = tuple(allfuncs)
|
||||||
|
@ -148,7 +148,7 @@ class _TiramisuOptionOptionDescription(CommonTiramisuOption):
|
|||||||
return self._option_bag.option
|
return self._option_bag.option
|
||||||
|
|
||||||
def type(self):
|
def type(self):
|
||||||
return self._option_bag.option.get_display_type()
|
return self._option_bag.option.get_type()
|
||||||
|
|
||||||
def isleadership(self):
|
def isleadership(self):
|
||||||
"""Test if option is a leader or a follower"""
|
"""Test if option is a leader or a follower"""
|
||||||
|
@ -12,6 +12,9 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
from typing import Any, List, Optional
|
||||||
|
from operator import add, mul, sub, truediv
|
||||||
|
from .setting import undefined
|
||||||
from .i18n import _
|
from .i18n import _
|
||||||
|
|
||||||
|
|
||||||
@ -79,3 +82,235 @@ class ParamIndex(Param):
|
|||||||
|
|
||||||
def tiramisu_copy(val): # pragma: no cover
|
def tiramisu_copy(val): # pragma: no cover
|
||||||
return val
|
return val
|
||||||
|
|
||||||
|
|
||||||
|
def calc_value(*args: List[Any],
|
||||||
|
multi: bool=False,
|
||||||
|
default: Any=undefined,
|
||||||
|
condition: Any=undefined,
|
||||||
|
expected: Any=undefined,
|
||||||
|
condition_operator: str='AND',
|
||||||
|
allow_none: bool=False,
|
||||||
|
remove_duplicate_value: bool=False,
|
||||||
|
join: Optional[str]=None,
|
||||||
|
min_args_len: Optional[int]=None,
|
||||||
|
operator: Optional[str]=None,
|
||||||
|
**kwargs) -> Any:
|
||||||
|
"""calculate value
|
||||||
|
:param multi: value returns must be a list of value
|
||||||
|
:param default: default value if condition is not matched or if args is empty
|
||||||
|
if there is more than one default value, set default_0, default_1, ...
|
||||||
|
:param condition: test if condition is equal to expected value
|
||||||
|
if there is more than one condition, set condition_0, condition_1, ...
|
||||||
|
:param expected: value expected for all conditions
|
||||||
|
if expected value is different between condition, set expected_0, expected_1, ...
|
||||||
|
: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: operator
|
||||||
|
|
||||||
|
examples:
|
||||||
|
* you want to copy value from an option to an other option:
|
||||||
|
>>> from tiramisu import calc_value, StrOption, OptionDescription, Config, Params, ParamOption
|
||||||
|
>>> val1 = StrOption('val1', '', 'val1')
|
||||||
|
>>> val2 = StrOption('val2', '', callback=calc_value, callback_params=Params(ParamOption(val1)))
|
||||||
|
>>> od = OptionDescription('root', '', [val1, val2])
|
||||||
|
>>> cfg = Config(od)
|
||||||
|
>>> cfg.value.dict()
|
||||||
|
{'val1': 'val1', 'val2': 'val1'}
|
||||||
|
|
||||||
|
* you want to copy values from two options in one multi option
|
||||||
|
>>> from tiramisu import calc_value, StrOption, OptionDescription, Config, Params, ParamOption, ParamValue
|
||||||
|
>>> val1 = StrOption('val1', "", 'val1')
|
||||||
|
>>> val2 = StrOption('val2', "", 'val2')
|
||||||
|
>>> val3 = StrOption('val3', "", multi=True, callback=calc_value, callback_params=Params((ParamOption(val1), ParamOption(val2)), multi=ParamValue(True)))
|
||||||
|
>>> od = OptionDescription('root', '', [val1, val2, val3])
|
||||||
|
>>> cfg = Config(od)
|
||||||
|
>>> cfg.value.dict()
|
||||||
|
{'val1': 'val1', 'val2': 'val2', 'val3': ['val1', 'val2']}
|
||||||
|
|
||||||
|
* you want to copy a value from an option is it not disabled, otherwise set 'default_value'
|
||||||
|
>>> from tiramisu import calc_value, StrOption, OptionDescription, Config, Params, ParamOption, ParamValue
|
||||||
|
>>> val1 = StrOption('val1', '', 'val1')
|
||||||
|
>>> val2 = StrOption('val2', '', callback=calc_value, callback_params=Params(ParamOption(val1, True), default=ParamValue('default_value')))
|
||||||
|
>>> od = OptionDescription('root', '', [val1, val2])
|
||||||
|
>>> cfg = Config(od)
|
||||||
|
>>> cfg.property.read_write()
|
||||||
|
>>> cfg.value.dict()
|
||||||
|
{'val1': 'val1', 'val2': 'val1'}
|
||||||
|
>>> cfg.option('val1').property.add('disabled')
|
||||||
|
>>> cfg.value.dict()
|
||||||
|
{'val2': 'default_value'}
|
||||||
|
|
||||||
|
* you want to copy value from an option is an other is True, otherwise set 'default_value'
|
||||||
|
>>> from tiramisu import calc_value, BoolOption, StrOption, OptionDescription, Config, Params, ParamOption, ParamValue
|
||||||
|
>>> boolean = BoolOption('boolean', '', True)
|
||||||
|
>>> val1 = StrOption('val1', '', 'val1')
|
||||||
|
>>> val2 = StrOption('val2', '', callback=calc_value, callback_params=Params(ParamOption(val1, True),
|
||||||
|
... default=ParamValue('default_value'),
|
||||||
|
... condition=ParamOption(boolean),
|
||||||
|
... expected=ParamValue(True)))
|
||||||
|
>>> od = OptionDescription('root', '', [boolean, val1, val2])
|
||||||
|
>>> cfg = Config(od)
|
||||||
|
>>> cfg.property.read_write()
|
||||||
|
>>> cfg.value.dict()
|
||||||
|
{'boolean': True, 'val1': 'val1', 'val2': 'val1'}
|
||||||
|
>>> cfg.option('boolean').value.set(False)
|
||||||
|
>>> cfg.value.dict()
|
||||||
|
{'boolean': False, 'val1': 'val1', 'val2': 'default_value'}
|
||||||
|
|
||||||
|
* you want to copy option even if None is present
|
||||||
|
>>> from tiramisu import calc_value, StrOption, OptionDescription, Config, Params, ParamOption, ParamValue
|
||||||
|
>>> val1 = StrOption('val1', "", 'val1')
|
||||||
|
>>> 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)))
|
||||||
|
>>> od = OptionDescription('root', '', [val1, val2, val3])
|
||||||
|
>>> cfg = Config(od)
|
||||||
|
>>> cfg.value.dict()
|
||||||
|
{'val1': 'val1', 'val2': None, 'val3': ['val1', None]}
|
||||||
|
|
||||||
|
* you want uniq value
|
||||||
|
>>> from tiramisu import calc_value, StrOption, OptionDescription, Config, Params, ParamOption, ParamValue
|
||||||
|
>>> val1 = StrOption('val1', "", '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)))
|
||||||
|
>>> od = OptionDescription('root', '', [val1, val2, val3])
|
||||||
|
>>> cfg = Config(od)
|
||||||
|
>>> cfg.value.dict()
|
||||||
|
{'val1': 'val1', 'val2': 'val1', 'val3': ['val1']}
|
||||||
|
|
||||||
|
|
||||||
|
* you want to join two values with '.'
|
||||||
|
>>> from tiramisu import calc_value, StrOption, OptionDescription, Config, Params, ParamOption, ParamValue
|
||||||
|
>>> val1 = StrOption('val1', "", 'val1')
|
||||||
|
>>> val2 = StrOption('val2', "", 'val2')
|
||||||
|
>>> val3 = StrOption('val3', "", callback=calc_value, callback_params=Params((ParamOption(val1), ParamOption(val2)), join=ParamValue('.')))
|
||||||
|
>>> od = OptionDescription('root', '', [val1, val2, val3])
|
||||||
|
>>> cfg = Config(od)
|
||||||
|
>>> cfg.value.dict()
|
||||||
|
{'val1': 'val1', 'val2': 'val2', 'val3': 'val1.val2'}
|
||||||
|
|
||||||
|
* you want join three values, only if almost three values are set
|
||||||
|
>>> from tiramisu import calc_value, StrOption, OptionDescription, Config, Params, ParamOption, ParamValue
|
||||||
|
>>> val1 = StrOption('val1', "", 'val1')
|
||||||
|
>>> val2 = StrOption('val2', "", 'val2')
|
||||||
|
>>> 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)))
|
||||||
|
>>> od = OptionDescription('root', '', [val1, val2, val3, val4])
|
||||||
|
>>> cfg = Config(od)
|
||||||
|
>>> cfg.property.read_write()
|
||||||
|
>>> cfg.value.dict()
|
||||||
|
{'val1': 'val1', 'val2': 'val2', 'val3': 'val3', 'val4': 'val1.val2.val3'}
|
||||||
|
>>> cfg.option('val3').property.add('disabled')
|
||||||
|
>>> cfg.value.dict()
|
||||||
|
{'val1': 'val1', 'val2': 'val2', 'val4': ''}
|
||||||
|
|
||||||
|
* you want to add all values
|
||||||
|
>>> from tiramisu import calc_value, IntOption, OptionDescription, Config, Params, ParamOption, ParamValue
|
||||||
|
>>> val1 = IntOption('val1', "", 1)
|
||||||
|
>>> val2 = IntOption('val2', "", 2)
|
||||||
|
>>> val3 = IntOption('val3', "", callback=calc_value, callback_params=Params((ParamOption(val1), ParamOption(val2)), operator=ParamValue('add')))
|
||||||
|
>>> od = OptionDescription('root', '', [val1, val2, val3])
|
||||||
|
>>> cfg = Config(od)
|
||||||
|
>>> cfg.value.dict()
|
||||||
|
{'val1': 1, 'val2': 2, 'val3': 3}
|
||||||
|
|
||||||
|
"""
|
||||||
|
def value_from_kwargs(value: Any, pattern: str, to_dict: bool=False) -> Any:
|
||||||
|
# if value attribute exist return it's value
|
||||||
|
# otherwise pattern_0, pattern_1, ...
|
||||||
|
# otherwise undefined
|
||||||
|
if value is not undefined:
|
||||||
|
if to_dict == 'all':
|
||||||
|
returns = {0: value}
|
||||||
|
else:
|
||||||
|
returns = value
|
||||||
|
else:
|
||||||
|
kwargs_matches = {}
|
||||||
|
len_pattern = len(pattern)
|
||||||
|
for key in kwargs.keys():
|
||||||
|
if key.startswith(pattern):
|
||||||
|
index = int(key[len_pattern:])
|
||||||
|
kwargs_matches[index] = kwargs[key]
|
||||||
|
if not kwargs_matches:
|
||||||
|
return undefined
|
||||||
|
keys = sorted(kwargs_matches)
|
||||||
|
if to_dict:
|
||||||
|
returns = {}
|
||||||
|
else:
|
||||||
|
returns = []
|
||||||
|
for key in keys:
|
||||||
|
if to_dict:
|
||||||
|
returns[key] = kwargs_matches[key]
|
||||||
|
else:
|
||||||
|
returns.append(kwargs_matches[key])
|
||||||
|
return returns
|
||||||
|
|
||||||
|
def is_condition_matches():
|
||||||
|
calculated_conditions = value_from_kwargs(condition, 'condition_', to_dict='all')
|
||||||
|
if condition is not undefined:
|
||||||
|
is_matches = None
|
||||||
|
calculated_expected = value_from_kwargs(expected, 'expected_', to_dict=True)
|
||||||
|
for idx, calculated_condition in calculated_conditions.items():
|
||||||
|
if isinstance(calculated_expected, dict):
|
||||||
|
current_matches = calculated_condition == calculated_expected[idx]
|
||||||
|
else:
|
||||||
|
current_matches = calculated_condition == calculated_expected
|
||||||
|
if is_matches is None:
|
||||||
|
is_matches = current_matches
|
||||||
|
elif condition_operator == 'AND':
|
||||||
|
is_matches = is_matches and current_matches
|
||||||
|
elif condition_operator == 'OR':
|
||||||
|
is_matches = is_matches or current_matches
|
||||||
|
else:
|
||||||
|
raise ValueError(_('unexpected {} condition_operator in calc_value').format(condition_operator))
|
||||||
|
else:
|
||||||
|
is_matches = True
|
||||||
|
return is_matches
|
||||||
|
|
||||||
|
def get_value():
|
||||||
|
if not is_condition_matches():
|
||||||
|
# force to default
|
||||||
|
value = []
|
||||||
|
else:
|
||||||
|
value = list(args)
|
||||||
|
if min_args_len and not len(value) >= min_args_len:
|
||||||
|
value = []
|
||||||
|
if value == []:
|
||||||
|
# default value
|
||||||
|
new_default = value_from_kwargs(default, 'default_')
|
||||||
|
if new_default is not undefined:
|
||||||
|
if not isinstance(new_default, list):
|
||||||
|
value = [new_default]
|
||||||
|
else:
|
||||||
|
value = new_default
|
||||||
|
return value
|
||||||
|
|
||||||
|
value = get_value()
|
||||||
|
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]
|
||||||
|
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
|
||||||
|
@ -27,6 +27,7 @@ from .option import Option
|
|||||||
class BoolOption(Option):
|
class BoolOption(Option):
|
||||||
"represents a choice between ``True`` and ``False``"
|
"represents a choice between ``True`` and ``False``"
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
|
_type = 'boolean'
|
||||||
_display_name = _('boolean')
|
_display_name = _('boolean')
|
||||||
|
|
||||||
def _validate(self,
|
def _validate(self,
|
||||||
|
@ -28,6 +28,7 @@ from .option import Option
|
|||||||
|
|
||||||
class BroadcastOption(Option):
|
class BroadcastOption(Option):
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
|
_type = 'broadcast_address'
|
||||||
_display_name = _('broadcast address')
|
_display_name = _('broadcast address')
|
||||||
|
|
||||||
def _validate(self,
|
def _validate(self,
|
||||||
|
@ -33,6 +33,7 @@ class ChoiceOption(Option):
|
|||||||
The option can also have the value ``None``
|
The option can also have the value ``None``
|
||||||
"""
|
"""
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
|
_type = 'choice'
|
||||||
_display_name = _('choice')
|
_display_name = _('choice')
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
|
@ -27,6 +27,7 @@ from .option import Option
|
|||||||
|
|
||||||
class DateOption(Option):
|
class DateOption(Option):
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
|
_type = 'date'
|
||||||
_display_name = _('date')
|
_display_name = _('date')
|
||||||
|
|
||||||
def _validate(self,
|
def _validate(self,
|
||||||
|
@ -19,15 +19,14 @@
|
|||||||
# the whole pypy projet is under MIT licence
|
# the whole pypy projet is under MIT licence
|
||||||
# ____________________________________________________________
|
# ____________________________________________________________
|
||||||
import re
|
import re
|
||||||
from ipaddress import ip_address, IPv4Address
|
from ipaddress import ip_address
|
||||||
|
|
||||||
from ..setting import undefined, Undefined, OptionBag
|
from ..setting import undefined, Undefined, OptionBag
|
||||||
from ..i18n import _
|
from ..i18n import _
|
||||||
from .option import Option
|
from .option import Option
|
||||||
from .stroption import StrOption
|
from .ipoption import IPOption
|
||||||
|
|
||||||
|
|
||||||
class DomainnameOption(StrOption):
|
class DomainnameOption(IPOption):
|
||||||
"""represents the choice of a domain name
|
"""represents the choice of a domain name
|
||||||
netbios: for MS domain
|
netbios: for MS domain
|
||||||
hostname: to identify the device
|
hostname: to identify the device
|
||||||
@ -35,6 +34,7 @@ class DomainnameOption(StrOption):
|
|||||||
fqdn: with tld, not supported yet
|
fqdn: with tld, not supported yet
|
||||||
"""
|
"""
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
|
_type = 'domainname'
|
||||||
_display_name = _('domain name')
|
_display_name = _('domain name')
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
@ -43,16 +43,17 @@ class DomainnameOption(StrOption):
|
|||||||
default=None,
|
default=None,
|
||||||
default_multi=None,
|
default_multi=None,
|
||||||
requires=None,
|
requires=None,
|
||||||
multi=False,
|
multi: bool=False,
|
||||||
callback=None,
|
callback=None,
|
||||||
callback_params=None,
|
callback_params=None,
|
||||||
validator=None,
|
validator=None,
|
||||||
validator_params=None,
|
validator_params=None,
|
||||||
properties=None,
|
properties=None,
|
||||||
allow_ip=False,
|
allow_ip: bool=False,
|
||||||
type_='domainname',
|
cidr: bool=False,
|
||||||
warnings_only=False,
|
type_: str='domainname',
|
||||||
allow_without_dot=False):
|
warnings_only: bool=False,
|
||||||
|
allow_without_dot=False) -> None:
|
||||||
|
|
||||||
if type_ not in ['netbios', 'hostname', 'domainname']:
|
if type_ not in ['netbios', 'hostname', 'domainname']:
|
||||||
raise ValueError(_('unknown type_ {0} for hostname').format(type_))
|
raise ValueError(_('unknown type_ {0} for hostname').format(type_))
|
||||||
@ -72,25 +73,29 @@ class DomainnameOption(StrOption):
|
|||||||
else:
|
else:
|
||||||
regexp = r'((?!-)[a-z0-9-]{{1,{0}}})'.format(self._get_len(type_))
|
regexp = r'((?!-)[a-z0-9-]{{1,{0}}})'.format(self._get_len(type_))
|
||||||
if allow_ip:
|
if allow_ip:
|
||||||
regexp = r'^(?:{0}|(?:(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){{3}}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)))$'.format(regexp)
|
if not cidr:
|
||||||
|
regexp = r'^(?:{0}|(?:(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){{3}}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)))$'.format(regexp)
|
||||||
|
else:
|
||||||
|
regexp = r'^(?:{0}|(?:(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){{3}}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/[0-9][0-9]))$'.format(regexp)
|
||||||
else:
|
else:
|
||||||
regexp = r'^{0}$'.format(regexp)
|
regexp = r'^{0}$'.format(regexp)
|
||||||
extra['_domain_re'] = re.compile(regexp)
|
extra['_domain_re'] = re.compile(regexp)
|
||||||
extra['_has_upper'] = re.compile('[A-Z]')
|
extra['_has_upper'] = re.compile('[A-Z]')
|
||||||
|
|
||||||
super(DomainnameOption, self).__init__(name,
|
super().__init__(name,
|
||||||
doc,
|
doc,
|
||||||
default=default,
|
default=default,
|
||||||
default_multi=default_multi,
|
default_multi=default_multi,
|
||||||
callback=callback,
|
callback=callback,
|
||||||
callback_params=callback_params,
|
callback_params=callback_params,
|
||||||
requires=requires,
|
requires=requires,
|
||||||
multi=multi,
|
multi=multi,
|
||||||
validator=validator,
|
validator=validator,
|
||||||
validator_params=validator_params,
|
validator_params=validator_params,
|
||||||
properties=properties,
|
properties=properties,
|
||||||
warnings_only=warnings_only,
|
warnings_only=warnings_only,
|
||||||
extra=extra)
|
cidr=cidr,
|
||||||
|
_extra=extra)
|
||||||
|
|
||||||
def _get_len(self, type_):
|
def _get_len(self, type_):
|
||||||
if type_ == 'netbios':
|
if type_ == 'netbios':
|
||||||
@ -116,9 +121,10 @@ class DomainnameOption(StrOption):
|
|||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
if self.impl_get_extra('_allow_ip') is True:
|
if self.impl_get_extra('_allow_ip') is False:
|
||||||
return
|
raise ValueError(_('must not be an IP'))
|
||||||
raise ValueError(_('must not be an IP'))
|
# it's an IP so validate with IPOption
|
||||||
|
return super()._validate(value, option_bag, current_opt)
|
||||||
part_name_length = self._get_len(self.impl_get_extra('_dom_type'))
|
part_name_length = self._get_len(self.impl_get_extra('_dom_type'))
|
||||||
if self.impl_get_extra('_dom_type') == 'domainname':
|
if self.impl_get_extra('_dom_type') == 'domainname':
|
||||||
if not self.impl_get_extra('_allow_without_dot') and not "." in value:
|
if not self.impl_get_extra('_allow_without_dot') and not "." in value:
|
||||||
|
@ -28,4 +28,5 @@ class EmailOption(RegexpOption):
|
|||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
#https://www.w3.org/TR/html-markup/input.email.html#input.email.attrs.value.single.
|
#https://www.w3.org/TR/html-markup/input.email.html#input.email.attrs.value.single.
|
||||||
_regexp = re.compile(r"^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$")
|
_regexp = re.compile(r"^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$")
|
||||||
|
_type = 'email'
|
||||||
_display_name = _('email address')
|
_display_name = _('email address')
|
||||||
|
@ -27,4 +27,5 @@ from .stroption import RegexpOption
|
|||||||
class FilenameOption(RegexpOption):
|
class FilenameOption(RegexpOption):
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
_regexp = re.compile(r"^[a-zA-Z0-9\-\._~/+]+$")
|
_regexp = re.compile(r"^[a-zA-Z0-9\-\._~/+]+$")
|
||||||
|
_type = 'filename'
|
||||||
_display_name = _('file name')
|
_display_name = _('file name')
|
||||||
|
@ -27,6 +27,7 @@ from .option import Option
|
|||||||
class FloatOption(Option):
|
class FloatOption(Option):
|
||||||
"represents a choice of a floating point number"
|
"represents a choice of a floating point number"
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
|
_type = 'float'
|
||||||
_display_name = _('float')
|
_display_name = _('float')
|
||||||
|
|
||||||
def _validate(self,
|
def _validate(self,
|
||||||
|
@ -27,6 +27,7 @@ from .option import Option
|
|||||||
class IntOption(Option):
|
class IntOption(Option):
|
||||||
"represents a choice of an integer"
|
"represents a choice of an integer"
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
|
_type = 'integer'
|
||||||
_display_name = _('integer')
|
_display_name = _('integer')
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
|
@ -32,6 +32,7 @@ from .networkoption import NetworkOption
|
|||||||
class IPOption(StrOption):
|
class IPOption(StrOption):
|
||||||
"represents the choice of an ip"
|
"represents the choice of an ip"
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
|
_type = 'ip'
|
||||||
_display_name = _('IP')
|
_display_name = _('IP')
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
@ -49,10 +50,15 @@ class IPOption(StrOption):
|
|||||||
private_only=False,
|
private_only=False,
|
||||||
allow_reserved=False,
|
allow_reserved=False,
|
||||||
warnings_only=False,
|
warnings_only=False,
|
||||||
cidr=False):
|
cidr=False,
|
||||||
extra = {'_private_only': private_only,
|
_extra=None):
|
||||||
'_allow_reserved': allow_reserved,
|
if _extra is None:
|
||||||
'_cidr': cidr}
|
extra = {}
|
||||||
|
else:
|
||||||
|
extra = _extra
|
||||||
|
extra['_private_only'] = private_only
|
||||||
|
extra['_allow_reserved'] = allow_reserved
|
||||||
|
extra['_cidr'] = cidr
|
||||||
super().__init__(name,
|
super().__init__(name,
|
||||||
doc,
|
doc,
|
||||||
default=default,
|
default=default,
|
||||||
|
@ -31,6 +31,7 @@ from .stroption import StrOption
|
|||||||
class NetmaskOption(StrOption):
|
class NetmaskOption(StrOption):
|
||||||
"represents the choice of a netmask"
|
"represents the choice of a netmask"
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
|
_type = 'netmask'
|
||||||
_display_name = _('netmask address')
|
_display_name = _('netmask address')
|
||||||
|
|
||||||
def _validate(self,
|
def _validate(self,
|
||||||
|
@ -28,6 +28,7 @@ from .option import Option
|
|||||||
class NetworkOption(Option):
|
class NetworkOption(Option):
|
||||||
"represents the choice of a network"
|
"represents the choice of a network"
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
|
_type = 'network'
|
||||||
_display_name = _('network address')
|
_display_name = _('network address')
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
|
@ -179,6 +179,10 @@ class Option(BaseOption):
|
|||||||
def impl_is_dynsymlinkoption(self) -> bool:
|
def impl_is_dynsymlinkoption(self) -> bool:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def get_type(self) -> str:
|
||||||
|
# _display_name for compatibility with older version than 3.0rc3
|
||||||
|
return getattr(self, '_type', self._display_name)
|
||||||
|
|
||||||
def get_display_type(self) -> str:
|
def get_display_type(self) -> str:
|
||||||
return self._display_name
|
return self._display_name
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ from .stroption import StrOption
|
|||||||
class PasswordOption(StrOption):
|
class PasswordOption(StrOption):
|
||||||
"represents the choice of a password"
|
"represents the choice of a password"
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
|
_type = 'password'
|
||||||
_display_name = _('password')
|
_display_name = _('password')
|
||||||
|
|
||||||
def _validate(self,
|
def _validate(self,
|
||||||
|
@ -40,6 +40,7 @@ class PortOption(StrOption):
|
|||||||
"""
|
"""
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
port_re = re.compile(r"^[0-9]*$")
|
port_re = re.compile(r"^[0-9]*$")
|
||||||
|
_type = 'port'
|
||||||
_display_name = _('port')
|
_display_name = _('port')
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
|
@ -29,6 +29,7 @@ from .option import Option
|
|||||||
class StrOption(Option):
|
class StrOption(Option):
|
||||||
"represents the choice of a string"
|
"represents the choice of a string"
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
|
_type = 'string'
|
||||||
_display_name = _('string')
|
_display_name = _('string')
|
||||||
|
|
||||||
def _validate(self,
|
def _validate(self,
|
||||||
|
@ -30,6 +30,7 @@ class URLOption(DomainnameOption):
|
|||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
proto_re = re.compile(r'(http|https)://')
|
proto_re = re.compile(r'(http|https)://')
|
||||||
path_re = re.compile(r"^[A-Za-z0-9\-\._~:/\?#\[\]@!%\$&\'\(\)\*\+,;=]+$")
|
path_re = re.compile(r"^[A-Za-z0-9\-\._~:/\?#\[\]@!%\$&\'\(\)\*\+,;=]+$")
|
||||||
|
_type = 'url'
|
||||||
_display_name = _('URL')
|
_display_name = _('URL')
|
||||||
|
|
||||||
def _validate(self,
|
def _validate(self,
|
||||||
|
@ -28,4 +28,5 @@ class UsernameOption(RegexpOption):
|
|||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
#regexp build with 'man 8 adduser' informations
|
#regexp build with 'man 8 adduser' informations
|
||||||
_regexp = re.compile(r"^[a-z_][a-z0-9_-]{0,30}[$a-z0-9_-]{0,1}$")
|
_regexp = re.compile(r"^[a-z_][a-z0-9_-]{0,30}[$a-z0-9_-]{0,1}$")
|
||||||
|
_type = 'username'
|
||||||
_display_name = _('username')
|
_display_name = _('username')
|
||||||
|
Reference in New Issue
Block a user