summaryrefslogtreecommitdiff
path: root/src/buildstream/_yaml.pyx
diff options
context:
space:
mode:
authorBenjamin Schubert <ben.c.schubert@gmail.com>2019-06-10 14:20:23 +0100
committerbst-marge-bot <marge-bot@buildstream.build>2019-07-15 14:14:02 +0000
commitd14b809cc7b56b7be9e3e40c2e12e8f7245ba680 (patch)
tree3afa82437bb3dcda6b63979c88c20d70f8dfd4f4 /src/buildstream/_yaml.pyx
parent38671fb53f4522d046bed94699db8cc344ac2862 (diff)
downloadbuildstream-d14b809cc7b56b7be9e3e40c2e12e8f7245ba680.tar.gz
_yaml: Add 'as_bool()' and 'is_none()' to ScalarNode
- 'as_bool()' casts a ScalarNode into a boolean, understanding both 'True' and 'False' as truthy-falsy values, as per node_get(type=bool) behavior - 'is_none()' allwos checking whether the scalar node contains a 'None' value. Since 'None' cannot be used when working with booleans, we need to have a way of checking for 'None' when we actually need the information of whether the value is unset. - Adapt all call places to use the new API
Diffstat (limited to 'src/buildstream/_yaml.pyx')
-rw-r--r--src/buildstream/_yaml.pyx27
1 files changed, 24 insertions, 3 deletions
diff --git a/src/buildstream/_yaml.pyx b/src/buildstream/_yaml.pyx
index f4f6c07e7..455abbc11 100644
--- a/src/buildstream/_yaml.pyx
+++ b/src/buildstream/_yaml.pyx
@@ -85,6 +85,25 @@ cdef class ScalarNode(Node):
self.line = line
self.column = column
+ cpdef bint is_none(self):
+ return self.value is None
+
+ cpdef bint as_bool(self) except *:
+ if type(self.value) is bool:
+ return self.value
+
+ # Don't coerce booleans to string, this makes "False" strings evaluate to True
+ if self.value in ('True', 'true'):
+ return True
+ elif self.value in ('False', 'false'):
+ return False
+ else:
+ provenance = node_get_provenance(self)
+ path = node_find_target(provenance.toplevel, self)[-1]
+ raise LoadError(LoadErrorReason.INVALID_DATA,
+ "{}: Value of '{}' is not of the expected type '{}'"
+ .format(provenance, path, bool.__name__, self.value))
+
cpdef str as_str(self):
# We keep 'None' as 'None' to simplify the API's usage and allow chaining for users
if self.value is None:
@@ -132,7 +151,7 @@ cdef class MappingNode(Node):
if type(value) is not ScalarNode:
if value is None:
- value = ScalarNode(None, _SYNTHETIC_FILE_INDEX, 0, next_synthetic_counter())
+ value = ScalarNode(None, self.file_index, 0, next_synthetic_counter())
else:
provenance = node_get_provenance(value)
raise LoadError(LoadErrorReason.INVALID_DATA,
@@ -141,6 +160,10 @@ cdef class MappingNode(Node):
return value
+ cpdef bint get_bool(self, str key, object default=_sentinel) except *:
+ cdef ScalarNode scalar = self.get_scalar(key, default)
+ return scalar.as_bool()
+
cpdef str get_str(self, str key, object default=_sentinel):
cdef ScalarNode scalar = self.get_scalar(key, default)
return scalar.as_str()
@@ -573,8 +596,6 @@ def dump(object contents, str filename=None):
# Returns: The Provenance of the dict, member or list element
#
cpdef ProvenanceInformation node_get_provenance(Node node, str key=None, list indices=None):
- assert type(node.value) is dict
-
if key is None:
# Retrieving the provenance for this node directly
return ProvenanceInformation(node)