summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Schubert <ben.c.schubert@gmail.com>2019-07-04 18:38:23 +0100
committerBenjamin Schubert <ben.c.schubert@gmail.com>2019-07-09 16:55:56 +0100
commit8b2193fde212479f3d6d0996a9493c6b51cee1ad (patch)
tree534700e55d51aef5cec309eba92c97fe5f2093c2
parentefee4f06e60e80dd62eddabddaad82ec08a50644 (diff)
downloadbuildstream-8b2193fde212479f3d6d0996a9493c6b51cee1ad.tar.gz
_yaml: Remove 'indices' from 'node_get_provenance'
With nodes being propagated better, we now don't need to extract provenance beforehand. Therefore removing the ability to provide indiced when getting provenance. - Also add 'scalar_at' on 'SequenceNode', in order to fetch a scalar node at a specific indice
-rw-r--r--src/buildstream/_options/optionarch.py2
-rw-r--r--src/buildstream/_options/optionpool.py18
-rw-r--r--src/buildstream/_yaml.pxd3
-rw-r--r--src/buildstream/_yaml.pyx29
-rw-r--r--tests/internals/yaml.py6
5 files changed, 29 insertions, 29 deletions
diff --git a/src/buildstream/_options/optionarch.py b/src/buildstream/_options/optionarch.py
index e7735eaa2..75be1a8ff 100644
--- a/src/buildstream/_options/optionarch.py
+++ b/src/buildstream/_options/optionarch.py
@@ -55,7 +55,7 @@ class OptionArch(OptionEnum):
# Do not terminate the loop early to ensure we validate
# all values in the list.
except PlatformError as e:
- provenance = _yaml.node_get_provenance(node, key='values', indices=[index])
+ provenance = _yaml.node_get_provenance(node.get_sequence('values').scalar_at(index))
prefix = ""
if provenance:
prefix = "{}: ".format(provenance)
diff --git a/src/buildstream/_options/optionpool.py b/src/buildstream/_options/optionpool.py
index 5155f62f4..f695c0acf 100644
--- a/src/buildstream/_options/optionpool.py
+++ b/src/buildstream/_options/optionpool.py
@@ -262,31 +262,27 @@ class OptionPool():
"{}: {}".format(p, assertion.strip()))
if conditions is not None:
-
- # Collect provenance first, we need to delete the (?) key
- # before any composition occurs.
- provenance = [
- _yaml.node_get_provenance(node, '(?)', indices=[i])
- for i in range(len(conditions))
- ]
del node['(?)']
- for condition, p in zip(conditions, provenance):
+ for condition in conditions:
tuples = list(condition.items())
if len(tuples) > 1:
+ provenance = _yaml.node_get_provenance(condition)
raise LoadError(LoadErrorReason.INVALID_DATA,
- "{}: Conditional statement has more than one key".format(p))
+ "{}: Conditional statement has more than one key".format(provenance))
expression, value = tuples[0]
try:
apply_fragment = self._evaluate(expression)
except LoadError as e:
# Prepend the provenance of the error
- raise LoadError(e.reason, "{}: {}".format(p, e)) from e
+ provenance = _yaml.node_get_provenance(condition)
+ raise LoadError(e.reason, "{}: {}".format(provenance, e)) from e
if type(value) is not _yaml.MappingNode: # pylint: disable=unidiomatic-typecheck
+ provenance = _yaml.node_get_provenance(condition)
raise LoadError(LoadErrorReason.ILLEGAL_COMPOSITE,
- "{}: Only values of type 'dict' can be composed.".format(p))
+ "{}: Only values of type 'dict' can be composed.".format(provenance))
# Apply the yaml fragment if its condition evaluates to true
if apply_fragment:
diff --git a/src/buildstream/_yaml.pxd b/src/buildstream/_yaml.pxd
index a3edd83f0..7b5209077 100644
--- a/src/buildstream/_yaml.pxd
+++ b/src/buildstream/_yaml.pxd
@@ -76,6 +76,7 @@ cdef class SequenceNode(Node):
cpdef void append(self, object value)
cpdef MappingNode mapping_at(self, int index)
cpdef Node node_at(self, int index, list allowed_types=*)
+ cpdef ScalarNode scalar_at(self, int index)
cpdef SequenceNode sequence_at(self, int index)
cpdef list as_str_list(self)
@@ -90,4 +91,4 @@ cdef class ProvenanceInformation:
cdef public bint is_synthetic
-cpdef ProvenanceInformation node_get_provenance(Node node, str key=*, list indices=*)
+cpdef ProvenanceInformation node_get_provenance(Node node, str key=*)
diff --git a/src/buildstream/_yaml.pyx b/src/buildstream/_yaml.pyx
index 24efd47d9..2df6a7d1b 100644
--- a/src/buildstream/_yaml.pyx
+++ b/src/buildstream/_yaml.pyx
@@ -620,15 +620,26 @@ cdef class SequenceNode(Node):
.format(provenance, path, MappingNode.__name__))
return value
- cpdef Node node_at(self, int key, list allowed_types = None):
- cdef value = self.value[key]
+ cpdef Node node_at(self, int index, list allowed_types = None):
+ cdef value = self.value[index]
if allowed_types and type(value) not in allowed_types:
provenance = node_get_provenance(self)
raise LoadError(LoadErrorReason.INVALID_DATA,
"{}: Value of '{}' is not one of the following: {}.".format(
- provenance, key, ", ".join(allowed_types)))
+ provenance, index, ", ".join(allowed_types)))
+
+ return value
+ cpdef ScalarNode scalar_at(self, int index):
+ value = self.value[index]
+
+ if type(value) is not ScalarNode:
+ provenance = node_get_provenance(self)
+ path = ["[{}]".format(p) for p in provenance.toplevel._find(self)] + ["[{}]".format(index)]
+ raise LoadError(LoadErrorReason.INVALID_DATA,
+ "{}: Value of '{}' is not of the expected type '{}'"
+ .format(provenance, path, ScalarNode.__name__))
return value
cpdef SequenceNode sequence_at(self, int index):
@@ -1122,23 +1133,15 @@ cpdef Node load_data(str data, int file_index=_SYNTHETIC_FILE_INDEX, str file_na
# Args:
# node (Node): a dictionary
# key (str): key in the dictionary
-# indices (list of indexes): Index path, in the case of list values
#
# Returns: The Provenance of the dict, member or list element
#
-cpdef ProvenanceInformation node_get_provenance(Node node, str key=None, list indices=None):
+cpdef ProvenanceInformation node_get_provenance(Node node, str key=None):
if key is None:
# Retrieving the provenance for this node directly
return ProvenanceInformation(node)
- if key and not indices:
- return ProvenanceInformation((<MappingNode> node).value.get(key))
-
- cdef Node nodeish = <Node> (<MappingNode> node).value.get(key)
- for idx in indices:
- nodeish = <Node> (<SequenceNode> nodeish).value[idx]
-
- return ProvenanceInformation(nodeish)
+ return ProvenanceInformation((<MappingNode> node).value.get(key))
# new_synthetic_file()
diff --git a/tests/internals/yaml.py b/tests/internals/yaml.py
index 37a2c9931..8ceed9d15 100644
--- a/tests/internals/yaml.py
+++ b/tests/internals/yaml.py
@@ -24,8 +24,8 @@ def test_load_yaml(datafiles):
assert loaded.get_str('kind') == 'pony'
-def assert_provenance(filename, line, col, node, key=None, indices=None):
- provenance = _yaml.node_get_provenance(node, key=key, indices=indices)
+def assert_provenance(filename, line, col, node, key=None):
+ provenance = _yaml.node_get_provenance(node, key=key)
assert isinstance(provenance, _yaml.ProvenanceInformation)
@@ -68,7 +68,7 @@ def test_element_provenance(datafiles):
loaded = _yaml.load(filename)
assert loaded.get_str('kind') == 'pony'
- assert_provenance(filename, 5, 2, loaded, 'moods', [1])
+ assert_provenance(filename, 5, 2, loaded.get_sequence('moods').scalar_at(1))
@pytest.mark.datafiles(os.path.join(DATA_DIR))