diff --git a/tiramisu/config.py b/tiramisu/config.py index 775845b..d9432fc 100644 --- a/tiramisu/config.py +++ b/tiramisu/config.py @@ -394,6 +394,15 @@ class Config(object): while self._cfgimpl_parent is not None: self = self._cfgimpl_parent return self + + def _cfgimpl_get_path(self): + subpath = [] + obj = self + while obj._cfgimpl_parent is not None: + subpath.insert(0, obj._cfgimpl_descr._name) + obj = obj._cfgimpl_parent + return ".".join(subpath) + def cfgimpl_previous_value(self, path): home, name = self._cfgimpl_get_home_by_path(path) diff --git a/tiramisu/error.py b/tiramisu/error.py index 4588f71..1ca0901 100644 --- a/tiramisu/error.py +++ b/tiramisu/error.py @@ -16,6 +16,8 @@ class MethodCallError(Exception): pass class RequiresError(Exception): pass +class RequirementRecursionError(RequiresError): + pass class MandatoryError(Exception): pass class SpecialOwnersError(Exception): diff --git a/tiramisu/option.py b/tiramisu/option.py index 75a2a07..28e33ae 100644 --- a/tiramisu/option.py +++ b/tiramisu/option.py @@ -23,7 +23,7 @@ from tiramisu.autolib import special_owners from tiramisu.basetype import HiddenBaseType, DisabledBaseType, ModeBaseType, modes from tiramisu.error import (ConfigError, ConflictConfigError, NotFoundError, - SpecialOwnersError, RequiresError) + SpecialOwnersError, RequiresError, RequirementRecursionError) available_actions = ['hide', 'show', 'enable', 'disable'] reverse_actions = {'hide': 'show', 'show': 'hide', 'disable':'enable', 'enable': 'disable'} @@ -498,6 +498,10 @@ def apply_requires(opt, config): name, expected, action, inverted = req if inverted == 'inverted': inverted = True + 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) # FIXME: doesn't work with 'auto' or 'fill' yet