diff options
author | Sam Thursfield <sam.thursfield@codethink.co.uk> | 2017-10-27 17:15:20 +0100 |
---|---|---|
committer | Tristan Van Berkom <tristan.van.berkom@gmail.com> | 2017-10-31 06:59:38 +0000 |
commit | 8c4d8ca2b7c886690fb933428c6768c745667db7 (patch) | |
tree | 853006ac4790d6fbe61802d53c19cc9ec2bdf830 | |
parent | 459cc8a2c16c1485cf891485caa61fec51e91b23 (diff) | |
download | buildstream-8c4d8ca2b7c886690fb933428c6768c745667db7.tar.gz |
Catch attempts to compose a list
Attempting to compose a list property would result in an unhandled
exception:
AttributeError: 'CommentedSeq' object has no attribute 'get'
We now at least detect the situation and produce an exception that
the frontend will report neatly:
Error loading pipeline: element.bst [line 11 column 4]: Only values of type 'dict' can be composed.
I was getting this error from an attempt to conditionally extend the
sources list:
sources:
(?):
arch == "x86_64":
- url: http://example.com/x86_64
The correct way to do this is to move the conditional into the parent
dict, e.g.:
(?):
arch == "x86_64":
sources:
- url: https://example.com/x86_64
It would be nice if the error message could hint at how the user can do
what they want, but it doesn't seem possible in this case.
-rw-r--r-- | buildstream/_yaml.py | 10 | ||||
-rw-r--r-- | tests/format/list-directive-type-error/element.bst | 6 | ||||
-rw-r--r-- | tests/format/list-directive-type-error/project.conf | 7 | ||||
-rw-r--r-- | tests/format/listdirectiveerrors.py | 15 |
4 files changed, 35 insertions, 3 deletions
diff --git a/buildstream/_yaml.py b/buildstream/_yaml.py index bba59c73c..8aa2ec714 100644 --- a/buildstream/_yaml.py +++ b/buildstream/_yaml.py @@ -743,13 +743,17 @@ def composite_dict(target, source, path=None): # Like composite_dict(), but raises an all purpose LoadError for convenience # def composite(target, source): - provenance = node_get_provenance(source) + if not hasattr(source, 'get'): + raise LoadError(LoadErrorReason.ILLEGAL_COMPOSITE, + "Only values of type 'dict' can be composed.") + + source_provenance = node_get_provenance(source) try: composite_dict(target, source) except CompositeTypeError as e: error_prefix = "" - if provenance: - error_prefix = "[%s]: " % str(provenance) + if source_provenance: + error_prefix = "[%s]: " % str(source_provenance) raise LoadError(LoadErrorReason.ILLEGAL_COMPOSITE, "%sExpected '%s' type for configuration '%s', instead received '%s'" % (error_prefix, diff --git a/tests/format/list-directive-type-error/element.bst b/tests/format/list-directive-type-error/element.bst new file mode 100644 index 000000000..4ac7d95bb --- /dev/null +++ b/tests/format/list-directive-type-error/element.bst @@ -0,0 +1,6 @@ +kind: autotools + +sources: + (?): + - arch == "x86_64": + - url: https://example.com/x86_64 diff --git a/tests/format/list-directive-type-error/project.conf b/tests/format/list-directive-type-error/project.conf new file mode 100644 index 000000000..dde56d7b8 --- /dev/null +++ b/tests/format/list-directive-type-error/project.conf @@ -0,0 +1,7 @@ +name: test + +options: + arch: + type: arch + description: Example architecture option + values: [ x86_32, x86_64 ] diff --git a/tests/format/listdirectiveerrors.py b/tests/format/listdirectiveerrors.py index 001b8a49d..9f2cfaaca 100644 --- a/tests/format/listdirectiveerrors.py +++ b/tests/format/listdirectiveerrors.py @@ -39,3 +39,18 @@ def test_element_error(cli, datafiles, target): assert result.exception assert isinstance(result.exception, LoadError) assert result.exception.reason == LoadErrorReason.TRAILING_LIST_DIRECTIVE + + +@pytest.mark.datafiles(DATA_DIR) +def test_project_error(cli, datafiles): + project = os.path.join(datafiles.dirname, datafiles.basename, 'list-directive-type-error') + result = cli.run(project=project, silent=True, args=[ + 'show', + '--deps', 'none', + '--format', '%{vars}', + 'element.bst']) + + assert result.exit_code != 0 + assert result.exception + assert isinstance(result.exception, LoadError) + assert result.exception.reason == LoadErrorReason.ILLEGAL_COMPOSITE |