diff options
author | Tristan Van Berkom <tristan.vanberkom@codethink.co.uk> | 2018-12-07 16:49:14 +0900 |
---|---|---|
committer | Tristan Van Berkom <tristan.vanberkom@codethink.co.uk> | 2018-12-07 16:57:13 +0900 |
commit | e61e6e50b74813f7a50f8c3a66f54b6682a427b8 (patch) | |
tree | 08ef7777ede77985de91c803f1ca3d97c50c1407 | |
parent | 2a6879a540ef28f4298f10e19924992bd179aea1 (diff) | |
download | buildstream-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.py | 7 |
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): |