add 'operator' to requirement

This commit is contained in:
2017-05-20 16:28:19 +02:00
parent f522fd0d53
commit 9b78f46e9d
6 changed files with 319 additions and 128 deletions

View File

@ -644,68 +644,85 @@ class Settings(object):
all_properties = None
for requires in current_requires:
for require in requires:
option, expected, action, inverse, \
transitive, same_action = require
reqpath = option.impl_getpath(context)
if reqpath == path or reqpath.startswith(path + '.'): # pragma: optional cover
raise RequirementError(_("malformed requirements "
"imbrication detected for option:"
" '{0}' with requirement on: "
"'{1}'").format(path, reqpath))
if option.impl_is_multi():
if index is None:
continue
idx = index
else:
idx = None
value = context.getattr(reqpath, force_permissive=True,
_setting_properties=setting_properties,
index=idx, returns_raise=True)
if isinstance(value, Exception):
if isinstance(value, PropertiesOptionError):
if not transitive:
if all_properties is None:
all_properties = []
for requires in opt.impl_getrequires():
for require in requires:
all_properties.append(require[2])
if not set(value.proptype) - set(all_properties):
continue
properties = value.proptype
if same_action and action not in properties: # pragma: optional cover
if len(properties) == 1:
prop_msg = _('property')
else:
prop_msg = _('properties')
raise RequirementError(_('cannot access to option "{0}" because '
'required option "{1}" has {2} {3}'
'').format(opt.impl_get_display_name(),
option.impl_get_display_name(),
prop_msg,
display_list(properties)))
orig_value = value
# transitive action, force expected
value = expected[0]
inverse = False
exps, action, inverse, \
transitive, same_action, operator = require
breaked = False
for exp in exps:
option, expected = exp
reqpath = option.impl_getpath(context)
if reqpath == path or reqpath.startswith(path + '.'): # pragma: optional cover
raise RequirementError(_("malformed requirements "
"imbrication detected for option:"
" '{0}' with requirement on: "
"'{1}'").format(path, reqpath))
if option.impl_is_multi():
if index is None:
# multi is allowed only for slaves
# so do not calculated requires if no index
continue
idx = index
else:
raise value
else:
orig_value = value
if (not inverse and value in expected or
inverse and value not in expected):
if debug:
if isinstance(orig_value, PropertiesOptionError):
for act, msg in orig_value._settings.apply_requires(**orig_value._datas).items():
calc_properties.setdefault(action, []).extend(msg)
idx = None
value = context.getattr(reqpath, force_permissive=True,
_setting_properties=setting_properties,
index=idx, returns_raise=True)
if isinstance(value, Exception):
if isinstance(value, PropertiesOptionError):
if not transitive:
if all_properties is None:
all_properties = []
for requires in opt.impl_getrequires():
for require in requires:
all_properties.append(require[1])
if not set(value.proptype) - set(all_properties):
continue
properties = value.proptype
if same_action and action not in properties: # pragma: optional cover
if len(properties) == 1:
prop_msg = _('property')
else:
prop_msg = _('properties')
raise RequirementError(_('cannot access to option "{0}" because '
'required option "{1}" has {2} {3}'
'').format(opt.impl_get_display_name(),
option.impl_get_display_name(),
prop_msg,
display_list(properties)))
orig_value = value
# transitive action, force expected
value = expected[0]
inverse = False
else:
if not inverse:
msg = _('the value of "{0}" is "{1}"')
else:
msg = _('the value of "{0}" is not "{1}"')
calc_properties.setdefault(action, []).append(msg.format(option.impl_get_display_name(), display_list(expected, 'or')))
raise value
else:
calc_properties.add(action)
orig_value = value
if (not inverse and value in expected or
inverse and value not in expected):
if operator != 'and':
if debug:
if isinstance(orig_value, PropertiesOptionError):
for msg in orig_value._settings.apply_requires(**orig_value._datas).values():
calc_properties.setdefault(action, []).extend(msg)
else:
if not inverse:
msg = _('the value of "{0}" is "{1}"')
else:
msg = _('the value of "{0}" is not "{1}"')
calc_properties.setdefault(action, []).append(
msg.format(option.impl_get_display_name(),
display_list(expected, 'or')))
else:
calc_properties.add(action)
breaked = True
break
elif operator == 'and':
break
else:
if operator == 'and':
calc_properties.add(action)
continue
if breaked:
break
return calc_properties
def get_modified_properties(self):