multi-action available now in requires
This commit is contained in:
parent
9b419a488d
commit
9e417334d4
2 changed files with 71 additions and 38 deletions
|
@ -38,6 +38,8 @@ class Config(object):
|
||||||
_cfgimpl_frozen = True
|
_cfgimpl_frozen = True
|
||||||
_cfgimpl_owner = default_owner
|
_cfgimpl_owner = default_owner
|
||||||
_cfgimpl_toplevel = None
|
_cfgimpl_toplevel = None
|
||||||
|
# TODO implement unicity by name
|
||||||
|
# _cfgimpl_unique_names = True
|
||||||
|
|
||||||
def __init__(self, descr, parent=None, **overrides):
|
def __init__(self, descr, parent=None, **overrides):
|
||||||
self._cfgimpl_descr = descr
|
self._cfgimpl_descr = descr
|
||||||
|
@ -61,6 +63,26 @@ class Config(object):
|
||||||
else:
|
else:
|
||||||
raise ConflictConfigError('duplicate option name: '
|
raise ConflictConfigError('duplicate option name: '
|
||||||
'{0}'.format(dup._name))
|
'{0}'.format(dup._name))
|
||||||
|
|
||||||
|
# TODO implement unicity by name
|
||||||
|
# def _validate_duplicates_for_names(self, children):
|
||||||
|
# "validates duplicates names agains the whole config"
|
||||||
|
# rootconfig = self._cfgimpl_get_toplevel()
|
||||||
|
# if self._cfgimpl_unique_names:
|
||||||
|
# for dup in children:
|
||||||
|
# try:
|
||||||
|
# print dup._name
|
||||||
|
# try:
|
||||||
|
# print rootconfig.get(dup._name)
|
||||||
|
# except AttributeError:
|
||||||
|
# pass
|
||||||
|
# raise NotFoundError
|
||||||
|
# #rootconfig.get(dup._name)
|
||||||
|
# except NotFoundError:
|
||||||
|
# pass # no identical names, it's fine
|
||||||
|
# else:
|
||||||
|
# raise ConflictConfigError('duplicate option name: '
|
||||||
|
# '{0}'.format(dup._name))
|
||||||
|
|
||||||
def _cfgimpl_build(self, overrides):
|
def _cfgimpl_build(self, overrides):
|
||||||
self._validate_duplicates(self._cfgimpl_descr._children)
|
self._validate_duplicates(self._cfgimpl_descr._children)
|
||||||
|
@ -424,7 +446,7 @@ class Config(object):
|
||||||
self.cfgimpl_unfreeze()
|
self.cfgimpl_unfreeze()
|
||||||
rootconfig = self._cfgimpl_get_toplevel()
|
rootconfig = self._cfgimpl_get_toplevel()
|
||||||
rootconfig.cfgimpl_enable_property('hidden')
|
rootconfig.cfgimpl_enable_property('hidden')
|
||||||
rootconfig.cfgimpl_disable_property('disabled')
|
rootconfig.cfgimpl_enable_property('disabled')
|
||||||
rootconfig._cfgimpl_mandatory = False
|
rootconfig._cfgimpl_mandatory = False
|
||||||
# ____________________________________________________________
|
# ____________________________________________________________
|
||||||
def getkey(self):
|
def getkey(self):
|
||||||
|
|
|
@ -23,10 +23,15 @@
|
||||||
from tiramisu.basetype import HiddenBaseType, DisabledBaseType
|
from tiramisu.basetype import HiddenBaseType, DisabledBaseType
|
||||||
from tiramisu.error import (ConfigError, ConflictConfigError, NotFoundError,
|
from tiramisu.error import (ConfigError, ConflictConfigError, NotFoundError,
|
||||||
RequiresError, RequirementRecursionError, MandatoryError)
|
RequiresError, RequirementRecursionError, MandatoryError)
|
||||||
available_actions = ['hide', 'show', 'enable', 'disable', 'freeze', 'unfreeze']
|
requires_actions = [('hide', 'show'), ('enable', 'disable'), ('freeze', 'unfreeze')]
|
||||||
reverse_actions = {'hide': 'show', 'show': 'hide',
|
|
||||||
'disable': 'enable', 'enable': 'disable',
|
available_actions = []
|
||||||
'freeze': 'unfreeze', 'unfreeze': 'freeze'}
|
reverse_actions = {}
|
||||||
|
for act1, act2 in requires_actions:
|
||||||
|
available_actions.extend([act1, act2])
|
||||||
|
reverse_actions[act1] = act2
|
||||||
|
reverse_actions[act2] = act1
|
||||||
|
|
||||||
# ____________________________________________________________
|
# ____________________________________________________________
|
||||||
# OptionDescription authorized group_type values
|
# OptionDescription authorized group_type values
|
||||||
group_types = ['default', 'family', 'group', 'master']
|
group_types = ['default', 'family', 'group', 'master']
|
||||||
|
@ -450,45 +455,51 @@ class OptionDescription(HiddenBaseType, DisabledBaseType):
|
||||||
if isinstance(child, OptionDescription):
|
if isinstance(child, OptionDescription):
|
||||||
child.enable()
|
child.enable()
|
||||||
# ____________________________________________________________
|
# ____________________________________________________________
|
||||||
|
|
||||||
|
def validate_requires_arg(requires, name):
|
||||||
|
# malformed requirements
|
||||||
|
config_action = []
|
||||||
|
for req in requires:
|
||||||
|
if not type(req) == tuple and len(req) != 3:
|
||||||
|
raise RequiresError("malformed requirements for option:"
|
||||||
|
" {0}".format(name))
|
||||||
|
action = req[2]
|
||||||
|
if action not in available_actions:
|
||||||
|
raise RequiresError("malformed requirements for option: {0}"
|
||||||
|
"unknown action: {1}".format(name, action))
|
||||||
|
if reverse_actions[action] in config_action:
|
||||||
|
raise RequiresError("inconsistency in action types for option: {0}"
|
||||||
|
"action: {1} in contradiction with {2}\n"
|
||||||
|
" ({3})".format(name, action,
|
||||||
|
reverse_actions[action], requires))
|
||||||
|
config_action.append(action)
|
||||||
|
|
||||||
|
def build_actions(requires):
|
||||||
|
trigger_actions = {}
|
||||||
|
for require in requires:
|
||||||
|
action = require[2]
|
||||||
|
trigger_actions.setdefault(action, []).append(require)
|
||||||
|
return trigger_actions
|
||||||
|
|
||||||
def apply_requires(opt, config):
|
def apply_requires(opt, config):
|
||||||
if hasattr(opt, '_requires'):
|
if hasattr(opt, '_requires') and opt._requires is not None:
|
||||||
if opt._requires is not None:
|
rootconfig = config._cfgimpl_get_toplevel()
|
||||||
# malformed requirements
|
validate_requires_arg(opt._requires, opt._name)
|
||||||
rootconfig = config._cfgimpl_get_toplevel()
|
# filters the callbacks
|
||||||
for req in opt._requires:
|
trigger_actions = build_actions(opt._requires)
|
||||||
if not type(req) == tuple and len(req) in (3, 4):
|
for requires in trigger_actions.values():
|
||||||
raise RequiresError("malformed requirements for option:"
|
|
||||||
" {0}".format(opt._name))
|
|
||||||
# all actions **must** be identical
|
|
||||||
actions = [req[2] for req in opt._requires]
|
|
||||||
action = actions[0]
|
|
||||||
for act in actions:
|
|
||||||
if act != action:
|
|
||||||
raise RequiresError("malformed requirements for option:"
|
|
||||||
" {0}".format(opt._name))
|
|
||||||
# filters the callbacks
|
|
||||||
matches = False
|
matches = False
|
||||||
for req in opt._requires:
|
for require in requires:
|
||||||
if len(req) == 3:
|
name, expected, action = require
|
||||||
name, expected, action = req
|
|
||||||
inverted = False
|
|
||||||
if len(req) == 4:
|
|
||||||
name, expected, action, inverted = req
|
|
||||||
if inverted == 'inverted':
|
|
||||||
inverted = True
|
|
||||||
path = config._cfgimpl_get_path() + '.' + opt._name
|
path = config._cfgimpl_get_path() + '.' + opt._name
|
||||||
if name.startswith(path):
|
if name.startswith(path):
|
||||||
raise RequirementRecursionError("malformed requirements imbrication "
|
raise RequirementRecursionError("malformed requirements "
|
||||||
"detected for option: '{0}' with requirement on: '{1}'".format(path, name))
|
"imbrication detected for option: '{0}' "
|
||||||
homeconfig, shortname = \
|
"with requirement on: '{1}'".format(path, name))
|
||||||
rootconfig._cfgimpl_get_home_by_path(name)
|
homeconfig, shortname = rootconfig._cfgimpl_get_home_by_path(name)
|
||||||
if shortname in homeconfig._cfgimpl_values:
|
if shortname in homeconfig._cfgimpl_values:
|
||||||
value = homeconfig._cfgimpl_values[shortname]
|
value = homeconfig._cfgimpl_values[shortname]
|
||||||
if (not inverted and value == expected) or \
|
if value == expected:
|
||||||
(inverted and value != expected):
|
|
||||||
if action not in available_actions:
|
|
||||||
raise RequiresError("malformed requirements"
|
|
||||||
" for option: {0}".format(opt._name))
|
|
||||||
getattr(opt, action)() #.hide() or show() or...
|
getattr(opt, action)() #.hide() or show() or...
|
||||||
# FIXME generic programming opt.property_launch(action, False)
|
# FIXME generic programming opt.property_launch(action, False)
|
||||||
matches = True
|
matches = True
|
||||||
|
|
Loading…
Reference in a new issue