summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Schubert <ben.c.schubert@gmail.com>2019-07-03 10:55:19 +0100
committerBenjamin Schubert <contact@benschubert.me>2019-07-03 16:57:26 +0000
commit3c84fc22b67ab92b6905c4797a4d7ad6ed6f4821 (patch)
treebea776330a1b6655bd4989acc18b79ba18740ec5
parent05496a31f72963180f0a382dc68ca1314d91b51c (diff)
downloadbuildstream-3c84fc22b67ab92b6905c4797a4d7ad6ed6f4821.tar.gz
_yaml: Remove 'node_extend_list' and add 'SequenceNode.append'
There was a single place using 'node_extend_list', which we can replace more easily with 'SequenceNode.append'. Also rewrite _projectrefs.py:_lookup to use the new API more effectively
-rw-r--r--src/buildstream/_projectrefs.py17
-rw-r--r--src/buildstream/_yaml.pxd1
-rw-r--r--src/buildstream/_yaml.pyx64
-rw-r--r--tests/internals/yaml.py14
4 files changed, 16 insertions, 80 deletions
diff --git a/src/buildstream/_projectrefs.py b/src/buildstream/_projectrefs.py
index d10456b14..c3e669c81 100644
--- a/src/buildstream/_projectrefs.py
+++ b/src/buildstream/_projectrefs.py
@@ -121,15 +121,16 @@ class ProjectRefs():
# Looks up a ref node in the project.refs file, creates one if ensure is True.
#
def _lookup(self, toplevel, project, element, source_index, *, ensure=False):
+ projects = toplevel.get_mapping('projects')
+
# Fetch the project
try:
- projects = toplevel.get_mapping('projects')
project_node = projects.get_mapping(project)
except LoadError:
if not ensure:
return None
- project_node = _yaml.new_empty_node(ref_node=projects)
- projects[project] = project_node
+ projects[project] = {}
+ project_node = projects.get_mapping(project)
# Fetch the element
try:
@@ -137,8 +138,8 @@ class ProjectRefs():
except LoadError:
if not ensure:
return None
- element_list = _yaml.new_empty_list_node()
- project_node[element] = element_list
+ project_node[element] = []
+ element_list = project_node.get_sequence(element)
# Fetch the source index
try:
@@ -147,9 +148,7 @@ class ProjectRefs():
if not ensure:
return None
- # Pad the list with empty newly created dictionaries
- _yaml.node_extend_list(project_node, element, source_index + 1, {})
-
- node = project_node.get_sequence(element).mapping_at(source_index)
+ element_list.append({})
+ node = element_list.mapping_at(source_index)
return node
diff --git a/src/buildstream/_yaml.pxd b/src/buildstream/_yaml.pxd
index 32a39dfd4..d7109bba5 100644
--- a/src/buildstream/_yaml.pxd
+++ b/src/buildstream/_yaml.pxd
@@ -67,6 +67,7 @@ cdef class ScalarNode(Node):
cdef class SequenceNode(Node):
+ cpdef void append(self, object value)
cpdef MappingNode mapping_at(self, int index)
cpdef SequenceNode sequence_at(self, int index)
cpdef list as_str_list(self)
diff --git a/src/buildstream/_yaml.pyx b/src/buildstream/_yaml.pyx
index fe5cdd426..b717b2eb3 100644
--- a/src/buildstream/_yaml.pyx
+++ b/src/buildstream/_yaml.pyx
@@ -558,6 +558,13 @@ cdef class SequenceNode(Node):
self.line = line
self.column = column
+ cpdef void append(self, object value):
+ if type(value) in [MappingNode, ScalarNode, SequenceNode]:
+ self.value.append(value)
+ else:
+ node = _create_node_recursive(value, self)
+ self.value.append(node)
+
cpdef SequenceNode copy(self):
cdef list copy = []
cdef Node entry
@@ -943,19 +950,6 @@ cdef class Representer:
return RepresenterState.init
-cdef Node _create_node(object value, int file_index, int line, int column):
- cdef type_value = type(value)
-
- if type_value in [bool, str, type(None), int]:
- return ScalarNode(value, file_index, line, column)
- elif type_value is dict:
- return MappingNode(value, file_index, line, column)
- elif type_value is list:
- return SequenceNode(value, file_index, line, column)
- raise ValueError(
- "Node values can only be 'list', 'dict', 'bool', 'str', 'int' or None. Not {}".format(type_value))
-
-
cdef Node _create_node_recursive(object value, Node ref_node):
cdef value_type = type(value)
@@ -1097,50 +1091,6 @@ cpdef ProvenanceInformation node_get_provenance(Node node, str key=None, list in
return ProvenanceInformation(nodeish)
-# node_extend_list()
-#
-# Extend a list inside a node to a given length, using the passed
-# default value to fill it out.
-#
-# Valid default values are:
-# Any string
-# An empty dict
-# An empty list
-#
-# Args:
-# node (node): The node
-# key (str): The list name in the node
-# length (int): The length to extend the list to
-# default (any): The default value to extend with.
-def node_extend_list(Node node, str key, Py_ssize_t length, object default):
- assert type(default) is str or default in ([], {})
-
- cdef Node list_node = <Node> node.value.get(key)
- if list_node is None:
- list_node = node.value[key] = SequenceNode([], node.file_index, node.line, next_synthetic_counter())
-
- cdef list the_list = list_node.value
- def_type = type(default)
-
- file_index = node.file_index
- if the_list:
- line_num = the_list[-1][2]
- else:
- line_num = list_node.line
-
- while length > len(the_list):
- if def_type is str:
- value = default
- elif def_type is list:
- value = []
- else:
- value = {}
-
- line_num += 1
-
- the_list.append(_create_node(value, file_index, line_num, next_synthetic_counter()))
-
-
# is_node()
#
# A test method which returns whether or not the passed in value
diff --git a/tests/internals/yaml.py b/tests/internals/yaml.py
index 9b3269d46..69f29a573 100644
--- a/tests/internals/yaml.py
+++ b/tests/internals/yaml.py
@@ -273,20 +273,6 @@ def test_list_deletion(datafiles):
assert not children
-# Test that extending a non-existent list works as expected
-@pytest.mark.datafiles(os.path.join(DATA_DIR))
-def test_nonexistent_list_extension(datafiles):
- base = os.path.join(datafiles.dirname, datafiles.basename, 'basics.yaml')
-
- base = _yaml.load(base, shortname='basics.yaml')
- assert 'todo' not in base
-
- _yaml.node_extend_list(base, 'todo', 3, 'empty')
-
- assert len(base.get_sequence('todo')) == 3
- assert base.get_sequence('todo').as_str_list() == ['empty', 'empty', 'empty']
-
-
# Tests for deep list composition
#
# Same as test_list_composition(), but adds an additional file