diff --git a/test/test_option_setting.py b/test/test_option_setting.py index df49cbc..7105e2d 100644 --- a/test/test_option_setting.py +++ b/test/test_option_setting.py @@ -50,6 +50,74 @@ def test_attribute_access(): assert api.option('string').value.get() == 'foo' +def test_mod_read_only_write(): + "default with multi is a list" + s = StrOption("string", "", default=[], default_multi="string", multi=True) + descr = OptionDescription("options", "", [s]) + config = Config(descr) + config2 = Config(descr) + assert config.property.getdefault() == {'cache', 'validator', 'warnings'} + assert config.property.getdefault('read_only', 'append') == {'frozen', + 'disabled', + 'validator', + 'everything_frozen', + 'mandatory', + 'empty', + 'force_store_value'} + assert config.property.getdefault('read_only', 'remove') == {'permissive', + 'hidden'} + assert config.property.getdefault('read_write', 'append') == {'frozen', + 'disabled', + 'validator', + 'hidden', + 'force_store_value'} + assert config.property.getdefault('read_write', 'remove') == {'permissive', + 'everything_frozen', + 'mandatory', + 'empty'} + # + config.property.setdefault({'cache'}) + config.property.setdefault(type='read_only', when='append', properties={'disabled'}) + config.property.setdefault(type='read_only', when='remove', properties={'hidden'}) + config.property.setdefault(type='read_write', when='append', properties={'disabled', + 'hidden'}) + config.property.setdefault(type='read_write', when='remove', properties=set([])) + + assert config.property.getdefault() == {'cache'} + assert config.property.getdefault('read_only', 'append') == {'disabled'} + assert config.property.getdefault('read_only', 'remove') == {'hidden'} + assert config.property.getdefault('read_write', 'append') == {'disabled', + 'hidden'} + assert config.property.getdefault('read_write', 'remove') == set([]) + # + config.property.read_only() + assert config.property.get() == {'cache', 'disabled'} + config.property.read_write() + assert config.property.get() == {'cache', 'disabled', 'hidden'} + config.property.read_only() + assert config.property.get() == {'cache', 'disabled'} + # + assert config2.property.getdefault() == {'cache', 'validator', 'warnings'} + assert config2.property.getdefault('read_only', 'append') == {'frozen', + 'disabled', + 'validator', + 'everything_frozen', + 'mandatory', + 'empty', + 'force_store_value'} + assert config2.property.getdefault('read_only', 'remove') == {'permissive', + 'hidden'} + assert config2.property.getdefault('read_write', 'append') == {'frozen', + 'disabled', + 'validator', + 'hidden', + 'force_store_value'} + assert config2.property.getdefault('read_write', 'remove') == {'permissive', + 'everything_frozen', + 'mandatory', + 'empty'} + + def test_setitem(): s = StrOption("string", "", default=["string", "sdfsdf"], default_multi="prout", multi=True) descr = OptionDescription("options", "", [s]) diff --git a/tiramisu/api.py b/tiramisu/api.py index d2df680..8f6c478 100644 --- a/tiramisu/api.py +++ b/tiramisu/api.py @@ -16,12 +16,13 @@ # ____________________________________________________________ from inspect import ismethod, getdoc, signature from time import time -from typing import List, Any, Optional, Callable, Union, Dict +from typing import List, Set, Any, Optional, Callable, Union, Dict from .error import APIError, ConfigError, SlaveError, PropertiesOptionError from .i18n import _ -from .setting import ConfigBag, OptionBag, owners, groups, Undefined, undefined, FORBIDDEN_SET_PROPERTIES +from .setting import ConfigBag, OptionBag, owners, groups, Undefined, undefined, \ + FORBIDDEN_SET_PROPERTIES, SPECIAL_PROPERTIES from .config import KernelConfig, SubConfig, KernelGroupConfig, KernelMetaConfig, KernelMixConfig from .option import ChoiceOption, OptionDescription @@ -919,10 +920,9 @@ class TiramisuContextProperty(TiramisuContext): old_props = self._config_bag.properties settings = self._config_bag.context.cfgimpl_get_settings() settings.read_write(self._config_bag.context) - #FIXME ? - permissives = frozenset(settings.get_context_permissives() | frozenset(['hidden'])) + or_properties = settings.rw_append - settings.ro_append - SPECIAL_PROPERTIES + permissives = frozenset(settings.get_context_permissives() | or_properties) settings.set_context_permissives(permissives) - #/FIXME ? del self._config_bag.properties if 'force_store_value' not in old_props and \ 'force_store_value' in self._config_bag.properties: @@ -976,8 +976,6 @@ class TiramisuContextProperty(TiramisuContext): else: force_store_value = False self._config_bag.context.cfgimpl_get_settings()._p_.importation(properties) - self._config_bag.context.cfgimpl_reset_cache(None, - None) del self._config_bag.properties if force_store_value: self._force_store_value() @@ -986,6 +984,53 @@ class TiramisuContextProperty(TiramisuContext): descr = self._config_bag.context.cfgimpl_get_description() descr.impl_build_force_store_values(self._config_bag) + def setdefault(self, + properties: Set[str], + type: Optional[str]=None, + when: Optional[str]=None) -> None: + if not isinstance(properties, set): + raise TypeError(_('properties must be a set')) + setting = self._config_bag.context.cfgimpl_get_settings() + if type is None and when is None: + setting.default_properties = properties + else: + if when not in ['append', 'remove']: + raise ValueError(_('unknown when {} (must be in append or remove)').format(when)) + if type == 'read_only': + if when == 'append': + setting.ro_append = properties + else: + setting.ro_remove = properties + elif type == 'read_write': + if when == 'append': + setting.rw_append = properties + else: + setting.rw_remove = properties + else: + raise ValueError(_('unknown type {}').format(type)) + + def getdefault(self, + type: Optional[str]=None, + when: Optional[str]=None) -> Set[str]: + setting = self._config_bag.context.cfgimpl_get_settings() + if type is None and when is None: + return setting.default_properties + + if when not in ['append', 'remove']: + raise ValueError(_('unknown when {} (must be in append or remove)').format(when)) + if type == 'read_only': + if when == 'append': + return setting.ro_append + else: + return setting.ro_remove + elif type == 'read_write': + if when == 'append': + return setting.rw_append + else: + return setting.rw_remove + else: + raise ValueError(_('unknown type {}').format(type)) + class TiramisuContextPermissive(TiramisuContext): """Manage config permissives""" diff --git a/tiramisu/setting.py b/tiramisu/setting.py index 955a4d6..b6c9a83 100644 --- a/tiramisu/setting.py +++ b/tiramisu/setting.py @@ -87,7 +87,8 @@ warnings demoting_error_warning all value errors are convert to warning (ValueErrorWarning) """ -default_properties = ('cache', 'validator', 'warnings') +DEFAULT_PROPERTIES = frozenset(['cache', 'validator', 'warnings']) +SPECIAL_PROPERTIES = {'frozen', 'mandatory', 'empty', 'force_store_value'} """Config can be in two defaut mode: @@ -101,12 +102,13 @@ read_write you can get all variables not disabled and not hidden you can set all variables not frozen """ -ro_append = set(['frozen', 'disabled', 'validator', 'everything_frozen', - 'mandatory', 'empty', 'force_store_value']) -ro_remove = set(['permissive', 'hidden']) -rw_append = set(['frozen', 'disabled', 'validator', 'hidden', - 'force_store_value']) -rw_remove = set(['permissive', 'everything_frozen', 'mandatory', 'empty']) +RO_APPEND = frozenset(['frozen', 'disabled', 'validator', 'everything_frozen', + 'mandatory', 'empty', 'force_store_value']) +RO_REMOVE = frozenset(['permissive', 'hidden']) +RW_APPEND = frozenset(['frozen', 'disabled', 'validator', 'hidden', + 'force_store_value']) +RW_REMOVE = frozenset(['permissive', 'everything_frozen', 'mandatory', + 'empty']) FORBIDDEN_SET_PROPERTIES = frozenset(['force_store_value']) @@ -344,7 +346,12 @@ class Settings(object): "``config.Config()``'s configuration options settings" __slots__ = ('_p_', '_pp_', - '__weakref__') + '__weakref__', + 'ro_append', + 'ro_remove', + 'rw_append', + 'rw_remove', + 'default_properties') def __init__(self, properties, @@ -361,6 +368,11 @@ class Settings(object): # generic owner self._p_ = properties self._pp_ = permissives + self.default_properties = DEFAULT_PROPERTIES + self.ro_append = RO_APPEND + self.ro_remove = RO_REMOVE + self.rw_append = RW_APPEND + self.rw_remove = RW_REMOVE # ____________________________________________________________ # get properties and permissive methods @@ -374,7 +386,7 @@ class Settings(object): 'context_props') if not is_cached: props = self._p_.getproperties(None, - default_properties) + self.default_properties) self._p_.setcache(None, None, props, @@ -711,10 +723,7 @@ class Settings(object): option_properties, config_properties, config_permissives): - properties = option_properties & config_properties - {'frozen', - 'mandatory', - 'empty', - 'force_store_value'} + properties = option_properties & config_properties - SPECIAL_PROPERTIES # remove global permissive properties if properties and ('permissive' in config_properties): properties -= config_permissives @@ -783,7 +792,7 @@ class Settings(object): append, context): props = self._p_.getproperties(None, - default_properties) + self.default_properties) modified = False if remove & props: props = props - remove @@ -798,13 +807,13 @@ class Settings(object): def read_only(self, context): "convenience method to freeze, hide and disable" - self._read(ro_remove, - ro_append, + self._read(self.ro_remove, + self.ro_append, context) def read_write(self, context): "convenience method to freeze, hide and disable" - self._read(rw_remove, - rw_append, + self._read(self.rw_remove, + self.rw_append, context)