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_owner = default_owner
|
||||
_cfgimpl_toplevel = None
|
||||
# TODO implement unicity by name
|
||||
# _cfgimpl_unique_names = True
|
||||
|
||||
def __init__(self, descr, parent=None, **overrides):
|
||||
self._cfgimpl_descr = descr
|
||||
|
@ -62,6 +64,26 @@ class Config(object):
|
|||
raise ConflictConfigError('duplicate option 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):
|
||||
self._validate_duplicates(self._cfgimpl_descr._children)
|
||||
for child in self._cfgimpl_descr._children:
|
||||
|
@ -424,7 +446,7 @@ class Config(object):
|
|||
self.cfgimpl_unfreeze()
|
||||
rootconfig = self._cfgimpl_get_toplevel()
|
||||
rootconfig.cfgimpl_enable_property('hidden')
|
||||
rootconfig.cfgimpl_disable_property('disabled')
|
||||
rootconfig.cfgimpl_enable_property('disabled')
|
||||
rootconfig._cfgimpl_mandatory = False
|
||||
# ____________________________________________________________
|
||||
def getkey(self):
|
||||
|
|
|
@ -23,10 +23,15 @@
|
|||
from tiramisu.basetype import HiddenBaseType, DisabledBaseType
|
||||
from tiramisu.error import (ConfigError, ConflictConfigError, NotFoundError,
|
||||
RequiresError, RequirementRecursionError, MandatoryError)
|
||||
available_actions = ['hide', 'show', 'enable', 'disable', 'freeze', 'unfreeze']
|
||||
reverse_actions = {'hide': 'show', 'show': 'hide',
|
||||
'disable': 'enable', 'enable': 'disable',
|
||||
'freeze': 'unfreeze', 'unfreeze': 'freeze'}
|
||||
requires_actions = [('hide', 'show'), ('enable', 'disable'), ('freeze', 'unfreeze')]
|
||||
|
||||
available_actions = []
|
||||
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
|
||||
group_types = ['default', 'family', 'group', 'master']
|
||||
|
@ -450,45 +455,51 @@ class OptionDescription(HiddenBaseType, DisabledBaseType):
|
|||
if isinstance(child, OptionDescription):
|
||||
child.enable()
|
||||
# ____________________________________________________________
|
||||
def apply_requires(opt, config):
|
||||
if hasattr(opt, '_requires'):
|
||||
if opt._requires is not None:
|
||||
|
||||
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):
|
||||
if hasattr(opt, '_requires') and opt._requires is not None:
|
||||
rootconfig = config._cfgimpl_get_toplevel()
|
||||
for req in opt._requires:
|
||||
if not type(req) == tuple and len(req) in (3, 4):
|
||||
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))
|
||||
validate_requires_arg(opt._requires, opt._name)
|
||||
# filters the callbacks
|
||||
trigger_actions = build_actions(opt._requires)
|
||||
for requires in trigger_actions.values():
|
||||
matches = False
|
||||
for req in opt._requires:
|
||||
if len(req) == 3:
|
||||
name, expected, action = req
|
||||
inverted = False
|
||||
if len(req) == 4:
|
||||
name, expected, action, inverted = req
|
||||
if inverted == 'inverted':
|
||||
inverted = True
|
||||
for require in requires:
|
||||
name, expected, action = require
|
||||
path = config._cfgimpl_get_path() + '.' + opt._name
|
||||
if name.startswith(path):
|
||||
raise RequirementRecursionError("malformed requirements imbrication "
|
||||
"detected for option: '{0}' with requirement on: '{1}'".format(path, name))
|
||||
homeconfig, shortname = \
|
||||
rootconfig._cfgimpl_get_home_by_path(name)
|
||||
raise RequirementRecursionError("malformed requirements "
|
||||
"imbrication detected for option: '{0}' "
|
||||
"with requirement on: '{1}'".format(path, name))
|
||||
homeconfig, shortname = rootconfig._cfgimpl_get_home_by_path(name)
|
||||
if shortname in homeconfig._cfgimpl_values:
|
||||
value = homeconfig._cfgimpl_values[shortname]
|
||||
if (not inverted and value == expected) or \
|
||||
(inverted and value != expected):
|
||||
if action not in available_actions:
|
||||
raise RequiresError("malformed requirements"
|
||||
" for option: {0}".format(opt._name))
|
||||
if value == expected:
|
||||
getattr(opt, action)() #.hide() or show() or...
|
||||
# FIXME generic programming opt.property_launch(action, False)
|
||||
matches = True
|
||||
|
|
Loading…
Reference in a new issue