in src/buildstream/_options/optionpool.py [0:0]
def _process_one_node(self, node, *, restricted=None):
conditions = node.get_sequence("(?)", default=None)
assertion = node.get_str("(!)", default=None)
# Process assersions first, we want to abort on the first encountered
# assertion in a given dictionary, and not lose an assertion due to
# it being overwritten by a later assertion which might also trigger.
if assertion is not None:
p = node.get_scalar("(!)").get_provenance()
raise LoadError("{}: {}".format(p, assertion.strip()), LoadErrorReason.USER_ASSERTION)
if conditions is not None:
del node["(?)"]
for condition in conditions:
tuples = list(condition.items())
if len(tuples) > 1:
provenance = condition.get_provenance()
raise LoadError(
"{}: Conditional statement has more than one key".format(provenance),
LoadErrorReason.INVALID_DATA,
)
expression, value = tuples[0]
try:
apply_fragment = self._evaluate(expression)
except LoadError as e:
# Prepend the provenance of the error
provenance = condition.get_provenance()
raise LoadError("{}: {}".format(provenance, e), e.reason) from e
if type(value) is not MappingNode: # pylint: disable=unidiomatic-typecheck
provenance = condition.get_provenance()
raise LoadError(
"{}: Only values of type 'dict' can be composed.".format(provenance),
LoadErrorReason.ILLEGAL_COMPOSITE,
)
# Observe restricted keys that are not allowed to be conditional
for key in restricted or []:
if key in value:
provenance = value.get_node(key).get_provenance()
raise LoadError(
"{}: The '{}' key cannot be specified conditionally.".format(provenance, key),
LoadErrorReason.ILLEGAL_COMPOSITE,
)
# Apply the yaml fragment if its condition evaluates to true
if apply_fragment:
value._composite(node)
return True
return False