multi-action available now in requires

This commit is contained in:
gwen 2012-09-20 10:51:35 +02:00
parent 9b419a488d
commit 9e417334d4
2 changed files with 71 additions and 38 deletions

View File

@ -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):

View File

@ -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 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'):
if opt._requires is not None:
# malformed requirements
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))
# filters the callbacks
if hasattr(opt, '_requires') and opt._requires is not None:
rootconfig = config._cfgimpl_get_toplevel()
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