requirement can have callback
This commit is contained in:
@ -465,8 +465,9 @@ class _TiramisuOptionValueOption:
|
||||
if isinstance(value, list):
|
||||
while undefined in value:
|
||||
idx = value.index(undefined)
|
||||
value[idx] = values.getdefaultvalue(self._option_bag,
|
||||
force_index=idx)
|
||||
soption_bag = self._option_bag.copy()
|
||||
soption_bag.index = idx
|
||||
value[idx] = values.getdefaultvalue(soption_bag)
|
||||
elif value == undefined:
|
||||
value = values.getdefaultvalue(self._option_bag)
|
||||
self._subconfig.setattr(value,
|
||||
|
@ -90,11 +90,11 @@ def manager_callback(callbk: Union[ParamOption, ParamValue],
|
||||
return value[index]
|
||||
return value
|
||||
except PropertiesOptionError as err:
|
||||
# raise because must not add value None in carry_out_calculation
|
||||
# raise PropertiesOptionError (which is catched) because must not add value None in carry_out_calculation
|
||||
if callbk.notraisepropertyerror:
|
||||
raise err
|
||||
raise ConfigError(_('unable to carry out a calculation for "{}"'
|
||||
', {}').format(option.impl_get_display_name(), err))
|
||||
', {}').format(option.impl_get_display_name(), err), err)
|
||||
|
||||
|
||||
def carry_out_calculation(option,
|
||||
|
@ -116,7 +116,7 @@ class PropertiesOptionError(AttributeError):
|
||||
self._name,
|
||||
prop_msg,
|
||||
msg))
|
||||
del self._requires, self._opt_type, self._name, self._option_bag
|
||||
del self._requires, self._opt_type, self._name
|
||||
del self._settings, self._orig_opt
|
||||
return self.msg
|
||||
|
||||
@ -127,7 +127,11 @@ class ConfigError(Exception):
|
||||
"""attempt to change an option's owner without a value
|
||||
or in case of `_cfgimpl_descr` is None
|
||||
or if a calculation cannot be carried out"""
|
||||
pass
|
||||
def __init__(self,
|
||||
exp,
|
||||
ori_err=None):
|
||||
super().__init__(exp)
|
||||
self.ori_err = ori_err
|
||||
|
||||
|
||||
class ConflictError(Exception):
|
||||
|
@ -49,9 +49,12 @@ class Param:
|
||||
|
||||
|
||||
class ParamOption(Param):
|
||||
__slots__ = ('option', 'notraisepropertyerror')
|
||||
def __init__(self, option, notraisepropertyerror=False):
|
||||
if not hasattr(option, 'impl_is_symlinkoption'):
|
||||
__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()
|
||||
@ -95,6 +98,7 @@ def calc_value(*args: List[Any],
|
||||
join: Optional[str]=None,
|
||||
min_args_len: Optional[int]=None,
|
||||
operator: Optional[str]=None,
|
||||
index: Optional[int]=None,
|
||||
**kwargs) -> Any:
|
||||
"""calculate value
|
||||
:param multi: value returns must be a list of value
|
||||
@ -181,7 +185,6 @@ def calc_value(*args: List[Any],
|
||||
>>> 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')
|
||||
@ -305,6 +308,11 @@ def calc_value(*args: List[Any],
|
||||
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:
|
||||
|
@ -170,7 +170,7 @@ class Base:
|
||||
param.option._add_dependency(self)
|
||||
if type_ == 'validator':
|
||||
self._has_dependency = True
|
||||
is_multi = self.impl_is_dynoptiondescription() or self.impl_is_multi()
|
||||
is_multi = self.impl_is_optiondescription() or self.impl_is_multi()
|
||||
func_args, func_kwargs, func_positional, func_keyword = self._get_function_args(calculator)
|
||||
calculator_args, calculator_kwargs = self._get_parameters_args(calculator_params, add_value)
|
||||
# remove knowned kwargs
|
||||
@ -253,13 +253,14 @@ class Base:
|
||||
def _impl_set_callback(self,
|
||||
callback: Callable,
|
||||
callback_params: Optional[Params]=None) -> None:
|
||||
if callback is None and callback_params is not None:
|
||||
raise ValueError(_("params defined for a callback function but "
|
||||
"no callback defined"
|
||||
' yet for option "{0}"').format(
|
||||
self.impl_getname()))
|
||||
self._validate_calculator(callback,
|
||||
callback_params)
|
||||
if __debug__:
|
||||
if callback is None and callback_params is not None:
|
||||
raise ValueError(_("params defined for a callback function but "
|
||||
"no callback defined"
|
||||
' yet for option "{0}"').format(
|
||||
self.impl_getname()))
|
||||
self._validate_calculator(callback,
|
||||
callback_params)
|
||||
if callback is not None:
|
||||
callback_params = self._build_calculator_params(callback,
|
||||
callback_params,
|
||||
@ -443,17 +444,25 @@ def validate_requires_arg(new_option: BaseOption,
|
||||
the description of the requires dictionary
|
||||
"""
|
||||
def get_option(require):
|
||||
option = require['option']
|
||||
if option == 'self':
|
||||
option = new_option
|
||||
if not isinstance(option, BaseOption):
|
||||
raise ValueError(_('malformed requirements '
|
||||
'must be an option in option {0}').format(name))
|
||||
if not multi and option.impl_is_multi():
|
||||
raise ValueError(_('malformed requirements '
|
||||
'multi option must not set '
|
||||
'as requires of non multi option {0}').format(name))
|
||||
option._add_dependency(new_option)
|
||||
if 'option' in require:
|
||||
option = require['option']
|
||||
if option == 'self':
|
||||
option = new_option
|
||||
if __debug__:
|
||||
if not isinstance(option, BaseOption):
|
||||
raise ValueError(_('malformed requirements '
|
||||
'must be an option in option {0}').format(name))
|
||||
if not multi and option.impl_is_multi():
|
||||
raise ValueError(_('malformed requirements '
|
||||
'multi option must not set '
|
||||
'as requires of non multi option {0}').format(name))
|
||||
option._add_dependency(new_option)
|
||||
else:
|
||||
callback = require['callback']
|
||||
callback_params = new_option._build_calculator_params(callback,
|
||||
require.get('callback_params'),
|
||||
'callback')
|
||||
option = (callback, callback_params)
|
||||
return option
|
||||
|
||||
def _set_expected(action,
|
||||
@ -482,11 +491,11 @@ def validate_requires_arg(new_option: BaseOption,
|
||||
operator = get_operator(require)
|
||||
if isinstance(expected, list):
|
||||
for exp in expected:
|
||||
if set(exp.keys()) != {'option', 'value'}:
|
||||
if __debug__ and set(exp.keys()) != {'option', 'value'}:
|
||||
raise ValueError(_('malformed requirements expected must have '
|
||||
'option and value for option {0}').format(name))
|
||||
option = get_option(exp)
|
||||
if option is not None:
|
||||
if __debug__:
|
||||
try:
|
||||
option._validate(exp['value'], undefined)
|
||||
except ValueError as err:
|
||||
@ -502,7 +511,7 @@ def validate_requires_arg(new_option: BaseOption,
|
||||
operator)
|
||||
else:
|
||||
option = get_option(require)
|
||||
if expected is not None:
|
||||
if __debug__ and not isinstance(option, tuple) and expected is not None:
|
||||
try:
|
||||
option._validate(expected, undefined)
|
||||
except ValueError as err:
|
||||
@ -560,25 +569,29 @@ def validate_requires_arg(new_option: BaseOption,
|
||||
# start parsing all requires given by user (has dict)
|
||||
# transforme it to a tuple
|
||||
for require in requires:
|
||||
if not isinstance(require, dict):
|
||||
raise ValueError(_("malformed requirements type for option:"
|
||||
" {0}, must be a dict").format(name))
|
||||
valid_keys = ('option', 'expected', 'action', 'inverse', 'transitive',
|
||||
'same_action', 'operator')
|
||||
unknown_keys = frozenset(require.keys()) - frozenset(valid_keys)
|
||||
if unknown_keys != frozenset():
|
||||
raise ValueError(_('malformed requirements for option: {0}'
|
||||
' unknown keys {1}, must only '
|
||||
'{2}').format(name,
|
||||
unknown_keys,
|
||||
valid_keys))
|
||||
# prepare all attributes
|
||||
if not ('expected' in require and isinstance(require['expected'], list)) and \
|
||||
not ('option' in require and 'expected' in require) or \
|
||||
'action' not in require:
|
||||
raise ValueError(_("malformed requirements for option: {0}"
|
||||
" require must have option, expected and"
|
||||
" action keys").format(name))
|
||||
if __debug__:
|
||||
if not isinstance(require, dict):
|
||||
raise ValueError(_("malformed requirements type for option:"
|
||||
" {0}, must be a dict").format(name))
|
||||
valid_keys = ('option', 'expected', 'action', 'inverse', 'transitive',
|
||||
'same_action', 'operator', 'callback', 'callback_params')
|
||||
unknown_keys = frozenset(require.keys()) - frozenset(valid_keys)
|
||||
if unknown_keys != frozenset():
|
||||
raise ValueError(_('malformed requirements for option: {0}'
|
||||
' unknown keys {1}, must only '
|
||||
'{2}').format(name,
|
||||
unknown_keys,
|
||||
valid_keys))
|
||||
# {'expected': ..., 'option': ..., 'action': ...}
|
||||
# {'expected': [{'option': ..., 'value': ...}, ...}], 'action': ...}
|
||||
# {'expected': ..., 'callback': ..., 'action': ...}
|
||||
if not 'expected' in require or not 'action' in require or \
|
||||
not (isinstance(require['expected'], list) or \
|
||||
'option' in require or \
|
||||
'callback' in require):
|
||||
raise ValueError(_("malformed requirements for option: {0}"
|
||||
" require must have option, expected and"
|
||||
" action keys").format(name))
|
||||
action = get_action(require)
|
||||
config_action.add(action)
|
||||
if action not in ret_requires:
|
||||
|
@ -109,7 +109,7 @@ class Leadership(OptionDescription):
|
||||
for requires_ in getattr(self, '_requires', ()):
|
||||
for require in requires_:
|
||||
for require_opt, values in require[0]:
|
||||
if require_opt.impl_is_multi() and require_opt.impl_get_leadership():
|
||||
if not isinstance(require_opt, tuple) and require_opt.impl_is_multi() and require_opt.impl_get_leadership():
|
||||
raise ValueError(_('malformed requirements option "{0}" '
|
||||
'must not be in follower for "{1}"').format(
|
||||
require_opt.impl_getname(),
|
||||
|
@ -139,7 +139,7 @@ class CacheOptionDescription(BaseOption):
|
||||
# * current option must be a follower (and only a follower)
|
||||
# * option in require and current option must be in same leadership
|
||||
for require_opt, values in require[0]:
|
||||
if require_opt.impl_is_multi():
|
||||
if not isinstance(require_opt, tuple) and require_opt.impl_is_multi():
|
||||
if is_follower is None:
|
||||
is_follower = option.impl_is_follower()
|
||||
if is_follower:
|
||||
|
@ -509,43 +509,59 @@ class Settings(object):
|
||||
exps, action, inverse, transitive, same_action, operator = require
|
||||
breaked = False
|
||||
for option, expected in exps:
|
||||
if option.issubdyn():
|
||||
option = option.to_dynoption(option_bag.option.rootpath,
|
||||
option_bag.option.impl_getsuffix())
|
||||
reqpath = option.impl_getpath()
|
||||
#FIXME too later!
|
||||
if reqpath.startswith(option_bag.path + '.'):
|
||||
raise RequirementError(_("malformed requirements "
|
||||
"imbrication detected for option:"
|
||||
" '{0}' with requirement on: "
|
||||
"'{1}'").format(option_bag.path, reqpath))
|
||||
idx = None
|
||||
is_indexed = False
|
||||
if option.impl_is_follower():
|
||||
idx = option_bag.index
|
||||
if idx is None:
|
||||
if not isinstance(option, tuple):
|
||||
if option.issubdyn():
|
||||
option = option.to_dynoption(option_bag.option.rootpath,
|
||||
option_bag.option.impl_getsuffix())
|
||||
reqpath = option.impl_getpath()
|
||||
if __debug__ and reqpath.startswith(option_bag.path + '.'):
|
||||
# FIXME too later!
|
||||
raise RequirementError(_("malformed requirements "
|
||||
"imbrication detected for option:"
|
||||
" '{0}' with requirement on: "
|
||||
"'{1}'").format(option_bag.path, reqpath))
|
||||
idx = None
|
||||
is_indexed = False
|
||||
if option.impl_is_follower():
|
||||
idx = option_bag.index
|
||||
if idx is None:
|
||||
continue
|
||||
elif option.impl_is_leader() and option_bag.index is None:
|
||||
continue
|
||||
elif option.impl_is_leader() and option_bag.index is None:
|
||||
continue
|
||||
elif option.impl_is_multi() and option_bag.index is not None:
|
||||
is_indexed = True
|
||||
config_bag = option_bag.config_bag.copy()
|
||||
soption_bag = OptionBag()
|
||||
soption_bag.set_option(option,
|
||||
reqpath,
|
||||
idx,
|
||||
config_bag)
|
||||
if option_bag.option == option:
|
||||
soption_bag.config_bag.unrestraint()
|
||||
soption_bag.config_bag.remove_validation()
|
||||
soption_bag.apply_requires = False
|
||||
elif option.impl_is_multi() and option_bag.index is not None:
|
||||
is_indexed = True
|
||||
config_bag = option_bag.config_bag.copy()
|
||||
soption_bag = OptionBag()
|
||||
soption_bag.set_option(option,
|
||||
reqpath,
|
||||
idx,
|
||||
config_bag)
|
||||
if option_bag.option == option:
|
||||
soption_bag.config_bag.unrestraint()
|
||||
soption_bag.config_bag.remove_validation()
|
||||
soption_bag.apply_requires = False
|
||||
else:
|
||||
soption_bag.config_bag.properties = soption_bag.config_bag.true_properties
|
||||
soption_bag.config_bag.set_permissive()
|
||||
else:
|
||||
soption_bag.config_bag.properties = soption_bag.config_bag.true_properties
|
||||
soption_bag.config_bag.set_permissive()
|
||||
if not option_bag.option.impl_is_optiondescription() and option_bag.option.impl_is_follower():
|
||||
idx = option_bag.index
|
||||
if idx is None:
|
||||
continue
|
||||
is_indexed = False
|
||||
try:
|
||||
value = context.getattr(reqpath,
|
||||
soption_bag)
|
||||
except PropertiesOptionError as err:
|
||||
if not isinstance(option, tuple):
|
||||
value = context.getattr(reqpath,
|
||||
soption_bag)
|
||||
else:
|
||||
value = context.cfgimpl_get_values().carry_out_calculation(option_bag,
|
||||
option[0],
|
||||
option[1])
|
||||
except (PropertiesOptionError, ConfigError) as err:
|
||||
if isinstance(err, ConfigError):
|
||||
if not isinstance(err.ori_err, PropertiesOptionError):
|
||||
raise err
|
||||
err = err.ori_err
|
||||
properties = err.proptype
|
||||
# if not transitive, properties must be verify in current requires
|
||||
# otherwise if same_action, property must be in properties
|
||||
@ -586,13 +602,19 @@ class Settings(object):
|
||||
inverse and value not in expected):
|
||||
if operator != 'and':
|
||||
if readable:
|
||||
if not inverse:
|
||||
msg = _('the value of "{0}" is {1}')
|
||||
display_value = display_list(expected, 'or', add_quote=True)
|
||||
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:
|
||||
msg = _('the value of "{0}" is not {1}')
|
||||
calc_properties.setdefault(action, []).append(
|
||||
msg.format(option.impl_get_display_name(),
|
||||
display_list(expected, 'or', add_quote=True)))
|
||||
name = option.impl_get_display_name()
|
||||
if not inverse:
|
||||
msg = _('the value of "{0}" is {1}').format(name, display_value)
|
||||
else:
|
||||
msg = _('the value of "{0}" is not {1}').format(name, display_value)
|
||||
calc_properties.setdefault(action, []).append(msg)
|
||||
else:
|
||||
calc_properties.add(action)
|
||||
breaked = True
|
||||
|
@ -16,10 +16,11 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ____________________________________________________________
|
||||
import weakref
|
||||
from typing import Optional
|
||||
from typing import Optional, Any, Callable
|
||||
from .error import ConfigError, PropertiesOptionError
|
||||
from .setting import owners, undefined, forbidden_owners, OptionBag, ConfigBag
|
||||
from .autolib import carry_out_calculation
|
||||
from .function import Params
|
||||
from .i18n import _
|
||||
|
||||
|
||||
@ -135,26 +136,48 @@ class Values(object):
|
||||
return self.getdefaultvalue(option_bag)
|
||||
|
||||
def getdefaultvalue(self,
|
||||
option_bag,
|
||||
force_index: Optional[int]=None):
|
||||
option_bag):
|
||||
"""get default value:
|
||||
- get meta config value or
|
||||
- get calculated value or
|
||||
- get default value
|
||||
:param opt: the `option.Option()` object
|
||||
:param path: path for `option.Option()` object
|
||||
:type path: str
|
||||
:param index: index of a multi/submulti
|
||||
:type index: int
|
||||
:returns: default value
|
||||
"""
|
||||
moption_bag = self._get_meta(option_bag)
|
||||
if moption_bag:
|
||||
# retrieved value from meta config
|
||||
return moption_bag.config_bag.context.cfgimpl_get_values().get_cached_value(moption_bag)
|
||||
|
||||
if option_bag.option.impl_has_callback():
|
||||
# default value is a calculated value
|
||||
value = self.calculate_value(option_bag)
|
||||
if value is not undefined:
|
||||
return value
|
||||
|
||||
# now try to get default value:
|
||||
value = option_bag.option.impl_getdefault()
|
||||
|
||||
# - if option is a submulti, return a list a list
|
||||
# - if option is a multi, return a list
|
||||
# - default value
|
||||
if option_bag.option.impl_is_multi() and option_bag.index is not None:
|
||||
# if index, must return good value for this index
|
||||
if len(value) > option_bag.index:
|
||||
value = value[option_bag.index]
|
||||
else:
|
||||
# no value for this index, retrieve default multi value
|
||||
# default_multi is already a list for submulti
|
||||
value = option_bag.option.impl_getdefault_multi()
|
||||
return value
|
||||
|
||||
def calculate_value(self,
|
||||
option_bag: OptionBag) -> Any:
|
||||
def _reset_cache(_value):
|
||||
if not 'expire' in option_bag.properties:
|
||||
return
|
||||
is_cache, cache_value = self._p_.getcache(option_bag.path,
|
||||
None,
|
||||
index,
|
||||
config_bag.properties,
|
||||
option_bag.index,
|
||||
option_bag.config_bag.properties,
|
||||
option_bag.properties,
|
||||
'value')
|
||||
if not is_cache or cache_value == _value:
|
||||
@ -162,75 +185,55 @@ class Values(object):
|
||||
# so do not invalidate cache
|
||||
return
|
||||
# calculated value is a new value, so reset cache
|
||||
config_bag.context.cfgimpl_reset_cache(option_bag)
|
||||
option_bag.config_bag.context.cfgimpl_reset_cache(option_bag)
|
||||
|
||||
config_bag = option_bag.config_bag
|
||||
opt = option_bag.option
|
||||
if force_index is not None:
|
||||
index = force_index
|
||||
else:
|
||||
index = option_bag.index
|
||||
moption_bag = self._get_meta(option_bag)
|
||||
if moption_bag:
|
||||
# retrieved value from meta config
|
||||
return moption_bag.config_bag.context.cfgimpl_get_values().get_cached_value(moption_bag)
|
||||
|
||||
if opt.impl_has_callback():
|
||||
# if value has callback, calculate value
|
||||
callback, callback_params = opt.impl_get_callback()
|
||||
value = carry_out_calculation(opt,
|
||||
callback=callback,
|
||||
callback_params=callback_params,
|
||||
index=index,
|
||||
config_bag=config_bag,
|
||||
fromconsistency=option_bag.fromconsistency)
|
||||
if isinstance(value, list) and index is not None:
|
||||
# if value is a list and index is set
|
||||
if opt.impl_is_submulti() and (value == [] or not isinstance(value[0], list)):
|
||||
# return value only if it's a submulti and not a list of list
|
||||
_reset_cache(value)
|
||||
return value
|
||||
|
||||
if len(value) > index:
|
||||
# return the value for specified index if found
|
||||
_reset_cache(value[index])
|
||||
return value[index]
|
||||
# there is no calculate value for this index,
|
||||
# so return an other default value
|
||||
else:
|
||||
if opt.impl_is_submulti():
|
||||
if isinstance(value, list):
|
||||
# value is a list, but no index specified
|
||||
if (value != [] and not isinstance(value[0], list)):
|
||||
# if submulti, return a list of value
|
||||
value = [value]
|
||||
elif index is not None:
|
||||
# if submulti, return a list of value
|
||||
value = [value]
|
||||
else:
|
||||
# return a list of list for a submulti
|
||||
value = [[value]]
|
||||
elif opt.impl_is_multi() and not isinstance(value, list) and index is None:
|
||||
# return a list for a multi
|
||||
value = [value]
|
||||
# if value has callback, calculate value
|
||||
callback, callback_params = option_bag.option.impl_get_callback()
|
||||
value = self.carry_out_calculation(option_bag,
|
||||
callback,
|
||||
callback_params)
|
||||
if isinstance(value, list) and option_bag.index is not None:
|
||||
# if value is a list and index is set
|
||||
if option_bag.option.impl_is_submulti() and (value == [] or not isinstance(value[0], list)):
|
||||
# return value only if it's a submulti and not a list of list
|
||||
_reset_cache(value)
|
||||
return value
|
||||
if len(value) > option_bag.index:
|
||||
# return the value for specified index if found
|
||||
_reset_cache(value[option_bag.index])
|
||||
return value[option_bag.index]
|
||||
# there is no calculate value for this index,
|
||||
# so return an other default value
|
||||
else:
|
||||
if option_bag.option.impl_is_submulti():
|
||||
if isinstance(value, list):
|
||||
# value is a list, but no index specified
|
||||
if (value != [] and not isinstance(value[0], list)):
|
||||
# if submulti, return a list of value
|
||||
value = [value]
|
||||
elif option_bag.index is not None:
|
||||
# if submulti, return a list of value
|
||||
value = [value]
|
||||
else:
|
||||
# return a list of list for a submulti
|
||||
value = [[value]]
|
||||
elif option_bag.option.impl_is_multi() and not isinstance(value, list) and option_bag.index is None:
|
||||
# return a list for a multi
|
||||
value = [value]
|
||||
_reset_cache(value)
|
||||
return value
|
||||
return undefined
|
||||
|
||||
# now try to get default value:
|
||||
# - if opt is a submulti, return a list a list
|
||||
# - if opt is a multi, return a list
|
||||
# - default value
|
||||
value = opt.impl_getdefault()
|
||||
if opt.impl_is_multi() and index is not None:
|
||||
# if index, must return good value for this index
|
||||
if len(value) > index:
|
||||
value = value[index]
|
||||
else:
|
||||
# no value for this index, retrieve default multi value
|
||||
# default_multi is already a list for submulti
|
||||
value = opt.impl_getdefault_multi()
|
||||
return value
|
||||
|
||||
def carry_out_calculation(self,
|
||||
option_bag: OptionBag,
|
||||
callback: Callable,
|
||||
callback_params: Optional[Params]) -> Any:
|
||||
return carry_out_calculation(option_bag.option,
|
||||
callback=callback,
|
||||
callback_params=callback_params,
|
||||
index=option_bag.index,
|
||||
config_bag=option_bag.config_bag,
|
||||
fromconsistency=option_bag.fromconsistency)
|
||||
def isempty(self,
|
||||
opt,
|
||||
value,
|
||||
|
Reference in New Issue
Block a user