summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTristan Van Berkom <tristan.vanberkom@codethink.co.uk>2018-12-07 16:49:14 +0900
committerTristan Van Berkom <tristan.vanberkom@codethink.co.uk>2018-12-07 16:57:13 +0900
commite61e6e50b74813f7a50f8c3a66f54b6682a427b8 (patch)
tree08ef7777ede77985de91c803f1ca3d97c50c1407
parent2a6879a540ef28f4298f10e19924992bd179aea1 (diff)
downloadbuildstream-e61e6e50b74813f7a50f8c3a66f54b6682a427b8.tar.gz
_yaml.py: Added `allow_none` parameter to _yaml.node_get()
This allows specifying whether or not the code believes a None value is acceptable if explicitly expressed to be None in the YAML. A previous patch 3ba544b80f9f268be8ffe62fc8589b30212ec4a2 changed the behavior to accept None for all values across the board, along with allowing explicitly setting the `default_value` to `None` which caused the code to be much more readable (this was the main motivation of the patch, but it had the side effect of allowing None for everything). In the majority of cases we load YAML however, it either has a value or it is not specified in the YAML, and None is hardly ever acceptable to be explicitly specified (it may be in the case you want to override something with nothing in the YAML, but it is the edge case). This had the side effect of causing unexpected crashes where the YAML specifies an empty dictionary for instance. Instead of forcing the caller to handle a possible None value, give the choice to the caller if they really want to accept a None value, and raise the LoadError otherwise. This fixes issue #803, which is a crash due to receival of an unexpected None value through _yaml.node_get()
-rw-r--r--buildstream/_yaml.py7
1 files changed, 4 insertions, 3 deletions
diff --git a/buildstream/_yaml.py b/buildstream/_yaml.py
index 4fe844a80..8d7302b80 100644
--- a/buildstream/_yaml.py
+++ b/buildstream/_yaml.py
@@ -352,6 +352,7 @@ _sentinel = object()
# key (str): The key to get a value for in node
# indices (list of ints): Optionally decend into lists of lists
# default_value: Optionally return this value if the key is not found
+# allow_none: (bool): Allow None to be a valid value
#
# Returns:
# The value if found in node, otherwise default_value is returned
@@ -362,7 +363,7 @@ _sentinel = object()
# Note:
# Returned strings are stripped of leading and trailing whitespace
#
-def node_get(node, expected_type, key, indices=None, default_value=_sentinel):
+def node_get(node, expected_type, key, indices=None, *, default_value=_sentinel, allow_none=False):
value = node.get(key, default_value)
provenance = node_get_provenance(node)
if value is _sentinel:
@@ -377,8 +378,8 @@ def node_get(node, expected_type, key, indices=None, default_value=_sentinel):
value = value[index]
path += '[{:d}]'.format(index)
- # We want to allow None as a valid value for any type
- if value is None:
+ # Optionally allow None as a valid value for any type
+ if value is None and (allow_none or default_value is None):
return None
if not isinstance(value, expected_type):