From d14b809cc7b56b7be9e3e40c2e12e8f7245ba680 Mon Sep 17 00:00:00 2001 From: Benjamin Schubert Date: Mon, 10 Jun 2019 14:20:23 +0100 Subject: _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 --- src/buildstream/_yaml.pyx | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) (limited to 'src/buildstream/_yaml.pyx') 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) -- cgit v1.2.1