Commit c1ddf063 authored by Karel Koci's avatar Karel Koci 🤘

euci: add support for getting and settings lists

This fixes handling of lists in euci.
parent 5134fd51
...@@ -43,11 +43,28 @@ class EUci(Uci): ...@@ -43,11 +43,28 @@ class EUci(Uci):
__BOOLEAN_TRUE = "1" __BOOLEAN_TRUE = "1"
__BOOLEAN_FALSE = "0" __BOOLEAN_FALSE = "0"
def _get(self, value, dtype):
if dtype == str:
return value
if dtype == bool:
value = value.lower()
if value not in self.__BOOLEAN_VALUES:
raise ValueError("invalid value '{}' for bool type".format(value))
return self.__BOOLEAN_VALUES[value]
if dtype == int:
return int(value)
raise TypeError("'{}' is not supported type of data".format(dtype))
def get(self, *args, dtype=str, **kwargs): def get(self, *args, dtype=str, **kwargs):
"""Get configuration value. """Get configuration value.
Up to three positional arguments are expected. Those are uci "config" Up to three positional arguments are expected. Those are uci "config"
"section" and "option" in this order. "section" and "option" in this order. "config" is the only one that is
really required.
Dictionary with all sections is returned when only "config" is
provided. If "section" and optionally also "option" is provided then it
returns single value or tuple of values in case of lists.
Following additional optional keywords arguments are available: Following additional optional keywords arguments are available:
dtype: data type to be returned. Currently supported are: str, bool and dtype: data type to be returned. Currently supported are: str, bool and
...@@ -57,28 +74,31 @@ class EUci(Uci): ...@@ -57,28 +74,31 @@ class EUci(Uci):
UciExceptionNotFound. UciExceptionNotFound.
When requested value is not found then this raises UciExceptionNotFound. When requested value is not found then this raises UciExceptionNotFound.
ValueError is raised in case of value that can't be converted to dtype.
""" """
kwdiff = set(kwargs).difference({'default'}) kwdiff = set(kwargs).difference({'default'})
if kwdiff: if kwdiff:
raise TypeError("'{}' is an invalid keyword argument for this function".format(kwdiff)) raise TypeError("'{}' is an invalid keyword argument for this function".format(kwdiff))
try: try:
value = super().get(*args) values = super().get(*args)
except UciExceptionNotFound: except UciExceptionNotFound:
if 'default' not in kwargs: if 'default' not in kwargs:
raise raise
value = str(kwargs['default']) values = kwargs['default']
if len(args) < 2:
# Only "config" was provided, values is dictionary and no conversion is provided.
return values
if dtype == str: if type(values) == tuple:
return value return tuple((self._get(str(value), dtype) for value in values))
return self._get(str(values), dtype)
def _set_value(self, value, dtype):
if dtype == bool: if dtype == bool:
value = value.lower() return self.__BOOLEAN_TRUE if value else self.__BOOLEAN_FALSE
if value not in self.__BOOLEAN_VALUES: # This implements handler for str and int type as well as fallback
raise ValueError return str(value)
return self.__BOOLEAN_VALUES[value]
if dtype == int:
return int(value)
raise TypeError("'{}' is not supported type of data".format(dtype))
def set(self, *args, **kwargs): def set(self, *args, **kwargs):
"""Set configuration value. """Set configuration value.
...@@ -101,12 +121,13 @@ class EUci(Uci): ...@@ -101,12 +121,13 @@ class EUci(Uci):
raise TypeError("'{}' is an invalid keyword argument for this function".format(kwdiff)) raise TypeError("'{}' is an invalid keyword argument for this function".format(kwdiff))
dtype = type(args[-1]) dtype = type(args[-1])
if dtype == bool: if dtype == tuple or dtype == list:
value = self.__BOOLEAN_TRUE if args[-1] else self.__BOOLEAN_FALSE # We consider first value as authoritative for type
dtype = type(args[-1][0]) if args[-1] else str
super().set(*args[:-1], tuple(
(self._set_value(value, dtype) for value in args[-1])))
else: else:
# This implements handler for str and int type as well as fallback super().set(*args[:-1], self._set_value(args[-1], dtype))
value = str(args[-1])
super().set(*args[:-1], value)
# Following methods are obsolete and should not be exnteded nor used in new code # # Following methods are obsolete and should not be exnteded nor used in new code #
......
...@@ -23,9 +23,12 @@ def test_get_string(tmpdir): ...@@ -23,9 +23,12 @@ def test_get_string(tmpdir):
tmpdir.join('test').write(""" tmpdir.join('test').write("""
config str 'str' config str 'str'
option foo 'value' option foo 'value'
list list 'value1'
list list 'value2'
""") """)
u = euci.EUci(confdir=tmpdir.strpath) u = euci.EUci(confdir=tmpdir.strpath)
assert u.get('test', 'str', 'foo') == 'value' assert u.get('test', 'str', 'foo') == 'value'
assert u.get('test', 'str', 'list') == ('value1', 'value2')
def test_set_string(tmpdir): def test_set_string(tmpdir):
...@@ -35,7 +38,9 @@ config testing 'testing' ...@@ -35,7 +38,9 @@ config testing 'testing'
""") """)
u = euci.EUci(savedir=tmpdir.mkdir('save').strpath, confdir=tmpdir.strpath) u = euci.EUci(savedir=tmpdir.mkdir('save').strpath, confdir=tmpdir.strpath)
u.set('test', 'testing', 'foo', 'value') u.set('test', 'testing', 'foo', 'value')
u.set('test', 'testing', 'list', ('f', 'o', 'o'))
assert u.get('test', 'testing', 'foo') == 'value' assert u.get('test', 'testing', 'foo') == 'value'
assert u.get('test', 'testing', 'list') == ('f', 'o', 'o')
def test_get_boolean(tmpdir): def test_get_boolean(tmpdir):
...@@ -60,6 +65,12 @@ config bool 'bool' ...@@ -60,6 +65,12 @@ config bool 'bool'
config bled 'bled' config bled 'bled'
option true 'enabled' option true 'enabled'
option false 'disabled' option false 'disabled'
config list 'list'
list true '1'
list true 'yes'
list false '0'
list false 'no'
""") """)
u = euci.EUci(confdir=tmpdir.strpath) u = euci.EUci(confdir=tmpdir.strpath)
assert u.get('test', 'integer', 'true', dtype=bool) assert u.get('test', 'integer', 'true', dtype=bool)
...@@ -67,11 +78,13 @@ config bled 'bled' ...@@ -67,11 +78,13 @@ config bled 'bled'
assert u.get('test', 'state', 'true', dtype=bool) assert u.get('test', 'state', 'true', dtype=bool)
assert u.get('test', 'bool', 'true', dtype=bool) assert u.get('test', 'bool', 'true', dtype=bool)
assert u.get('test', 'bled', 'true', dtype=bool) assert u.get('test', 'bled', 'true', dtype=bool)
assert u.get('test', 'list', 'true', dtype=bool) == (True, True)
assert not u.get('test', 'integer', 'false', dtype=bool) assert not u.get('test', 'integer', 'false', dtype=bool)
assert not u.get('test', 'word', 'false', dtype=bool) assert not u.get('test', 'word', 'false', dtype=bool)
assert not u.get('test', 'state', 'false', dtype=bool) assert not u.get('test', 'state', 'false', dtype=bool)
assert not u.get('test', 'bool', 'false', dtype=bool) assert not u.get('test', 'bool', 'false', dtype=bool)
assert not u.get('test', 'bled', 'false', dtype=bool) assert not u.get('test', 'bled', 'false', dtype=bool)
assert u.get('test', 'list', 'false', dtype=bool) == (False, False)
def test_set_boolean(tmpdir): def test_set_boolean(tmpdir):
...@@ -82,8 +95,10 @@ config testing 'testing' ...@@ -82,8 +95,10 @@ config testing 'testing'
u = euci.EUci(savedir=tmpdir.mkdir('save').strpath, confdir=tmpdir.strpath) u = euci.EUci(savedir=tmpdir.mkdir('save').strpath, confdir=tmpdir.strpath)
u.set('test', 'testing', 'true', True) u.set('test', 'testing', 'true', True)
u.set('test', 'testing', 'false', False) u.set('test', 'testing', 'false', False)
u.set('test', 'testing', 'list', (True, False, True, False))
assert u.get('test', 'testing', 'true') == '1' assert u.get('test', 'testing', 'true') == '1'
assert u.get('test', 'testing', 'false') == '0' assert u.get('test', 'testing', 'false') == '0'
assert u.get('test', 'testing', 'list') == ('1', '0', '1', '0')
def test_get_integer(tmpdir): def test_get_integer(tmpdir):
...@@ -92,10 +107,15 @@ def test_get_integer(tmpdir): ...@@ -92,10 +107,15 @@ def test_get_integer(tmpdir):
config integer 'integer' config integer 'integer'
option plus '42' option plus '42'
option minus '-42' option minus '-42'
list primes '2'
list primes '3'
list primes '5'
list primes '7'
""") """)
u = euci.EUci(confdir=tmpdir.strpath) u = euci.EUci(confdir=tmpdir.strpath)
assert u.get('test', 'integer', 'plus', dtype=int) == 42 assert u.get('test', 'integer', 'plus', dtype=int) == 42
assert u.get('test', 'integer', 'minus', dtype=int) == -42 assert u.get('test', 'integer', 'minus', dtype=int) == -42
assert u.get('test', 'integer', 'primes', dtype=int) == (2, 3, 5, 7)
def test_set_integer(tmpdir): def test_set_integer(tmpdir):
...@@ -106,8 +126,10 @@ config testing 'testing' ...@@ -106,8 +126,10 @@ config testing 'testing'
u = euci.EUci(savedir=tmpdir.mkdir('save').strpath, confdir=tmpdir.strpath) u = euci.EUci(savedir=tmpdir.mkdir('save').strpath, confdir=tmpdir.strpath)
u.set('test', 'testing', 'plus', 42) u.set('test', 'testing', 'plus', 42)
u.set('test', 'testing', 'minus', -42) u.set('test', 'testing', 'minus', -42)
u.set('test', 'testing', 'primes', (2, 3, 5, 7))
assert u.get('test', 'testing', 'plus') == '42' assert u.get('test', 'testing', 'plus') == '42'
assert u.get('test', 'testing', 'minus') == '-42' assert u.get('test', 'testing', 'minus') == '-42'
assert u.get('test', 'testing', 'primes') == ('2', '3', '5', '7')
def test_get_default(tmpdir): def test_get_default(tmpdir):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment