summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDominik Holland <dominik.holland@qt.io>2022-01-27 10:42:52 +0100
committerDominik Holland <dominik.holland@googlemail.com>2022-01-27 13:50:04 +0100
commit3703c77aa9014aeff71ea455710cc627cd5c562c (patch)
treec562a691fdb48b37b7161b4c0a407e8a4c9669fb
parent71f21afe3afce5a86f9908b8854170c8c19e05c7 (diff)
downloadqtivi-qface-3703c77aa9014aeff71ea455710cc627cd5c562c.tar.gz
Improve error handling when parsing annotation files
The System.lookup() function is now throwing an exception when the name couldn't be found, instead of just returning None. This exception is catched in the FileSystem object and printed on stderr. In strict mode, any annotation error results in exiting the generator. Fixes: #90
-rw-r--r--qface/generator.py17
-rw-r--r--qface/idl/domain.py6
-rw-r--r--tests/in/broken_tuner_annotations.yaml3
-rw-r--r--tests/in/invalid_tuner_annotations.yaml3
-rw-r--r--tests/in/tuner_annotations.yaml3
-rw-r--r--tests/test_tags.py28
6 files changed, 53 insertions, 7 deletions
diff --git a/qface/generator.py b/qface/generator.py
index d84a04c..297c2ef 100644
--- a/qface/generator.py
+++ b/qface/generator.py
@@ -345,10 +345,15 @@ class FileSystem(object):
return
meta = FileSystem.load_yaml(document)
click.secho('merge: {0}'.format(document.name), fg='blue')
- for identifier, data in meta.items():
- symbol = system.lookup(identifier)
- if symbol:
- merge(symbol.tags, data)
+ try:
+ for identifier, data in meta.items():
+ symbol = system.lookup(identifier)
+ if symbol:
+ merge(symbol.tags, data)
+ except Exception as e:
+ click.secho('Error parsing annotation {0}: {1}'.format(document, e), fg='red', err=True)
+ if FileSystem.strict:
+ sys.exit(-1)
@staticmethod
def parse(input, identifier: str = None, use_cache=False, clear_cache=True, pattern="*.qface", profile=EProfile.FULL):
@@ -391,6 +396,8 @@ class FileSystem(object):
if not document.exists():
if required:
click.secho('yaml document does not exists: {0}'.format(document), fg='red', err=True)
+ if FileSystem.strict:
+ sys.exit(-1)
return {}
try:
return yaml.load(document.text(), Loader=Loader)
@@ -399,4 +406,6 @@ class FileSystem(object):
if hasattr(exc, 'problem_mark'):
error = '{0}:{1}'.format(error, exc.problem_mark.line+1)
click.secho('{0}: error: {1}'.format(error, str(exc)), fg='red', err=True)
+ if FileSystem.strict:
+ sys.exit(-1)
return {}
diff --git a/qface/idl/domain.py b/qface/idl/domain.py
index 7949e6c..fbd0175 100644
--- a/qface/idl/domain.py
+++ b/qface/idl/domain.py
@@ -55,10 +55,10 @@ class System(object):
return self._moduleMap[name]
# <module>.<Symbol>
(module_name, type_name, fragment_name) = self.split_typename(name)
- if not module_name and type_name:
- click.secho('not able to lookup symbol: {0}'.format(name), fg='red')
- return None
+ if not module_name in self._moduleMap:
+ raise Exception('not able to lookup symbol: {0}'.format(name))
module = self._moduleMap[module_name]
+ # The module lookup calls this function again if the type_name doesn't exist
return module.lookup(type_name, fragment_name)
@staticmethod
diff --git a/tests/in/broken_tuner_annotations.yaml b/tests/in/broken_tuner_annotations.yaml
new file mode 100644
index 0000000..a05536a
--- /dev/null
+++ b/tests/in/broken_tuner_annotations.yaml
@@ -0,0 +1,3 @@
+com.pelagicore.ivi.tuner.Tuner{
+ extra:
+ extraA: true
diff --git a/tests/in/invalid_tuner_annotations.yaml b/tests/in/invalid_tuner_annotations.yaml
new file mode 100644
index 0000000..564aaf4
--- /dev/null
+++ b/tests/in/invalid_tuner_annotations.yaml
@@ -0,0 +1,3 @@
+com.pelagicore.ivi.tuner.Tunerrrrrrrr:
+ extra:
+ extraA: true
diff --git a/tests/in/tuner_annotations.yaml b/tests/in/tuner_annotations.yaml
new file mode 100644
index 0000000..bff1d8b
--- /dev/null
+++ b/tests/in/tuner_annotations.yaml
@@ -0,0 +1,3 @@
+com.pelagicore.ivi.tuner.Tuner:
+ extra:
+ extraA: true
diff --git a/tests/test_tags.py b/tests/test_tags.py
index 82f2c90..0e70143 100644
--- a/tests/test_tags.py
+++ b/tests/test_tags.py
@@ -1,4 +1,6 @@
from qface.generator import FileSystem
+from unittest.mock import patch
+from io import StringIO
import logging
import logging.config
from path import Path
@@ -57,5 +59,31 @@ def test_flag():
assert interface.attribute('config', 'c') == 'C' # use value from IDL
assert interface.tags['data'] == [1, 2, 3] # array annotatiom
+def test_merge_annotation():
+ system = loadTuner()
+ interface = system.lookup('com.pelagicore.ivi.tuner.Tuner')
+ assert interface
+ assert interface.attribute('config', 'private') is True
+ assert interface.attribute('extra', 'extraA') is None
+ FileSystem.merge_annotations(system, inputPath / 'tuner_annotations.yaml')
+ assert interface.attribute('extra', 'extraA') is True
+
+@patch('sys.stderr', new_callable=StringIO)
+def test_merge_broken_annotation(mock_stderr):
+ system = loadTuner()
+ interface = system.lookup('com.pelagicore.ivi.tuner.Tuner')
+ assert interface
+ FileSystem.merge_annotations(system, inputPath / 'broken_tuner_annotations.yaml')
+
+ assert interface.attribute('extra', 'extraA') is None
+ assert mock_stderr.getvalue().__contains__("tests/in/broken_tuner_annotations.yaml:2: error: mapping values are not allowed")
+@patch('sys.stderr', new_callable=StringIO)
+def test_merge_invalid_annotation(mock_stderr):
+ system = loadTuner()
+ interface = system.lookup('com.pelagicore.ivi.tuner.Tuner')
+ assert interface
+ FileSystem.merge_annotations(system, inputPath / 'invalid_tuner_annotations.yaml')
+ assert interface.attribute('extra', 'extraA') is None
+ assert mock_stderr.getvalue() == "Error parsing annotation tests/in/invalid_tuner_annotations.yaml: not able to lookup symbol: Tunerrrrrrrr\n"