qapi/parser: enforce all top-level expressions must be dict in _parse()

Instead of using get_expr nested=False, allow get_expr to always return
any expression. In exchange, add a new error message to the top-level
parser that explains the semantic error: Top-level expressions must
always be JSON objects.

This helps mypy understand the rest of this function which assumes that
get_expr did indeed return a dict.

The exception type changes from QAPIParseError to QAPISemError as a
result, and the error message in two tests now changes.

Signed-off-by: John Snow <jsnow@redhat.com>

Message-Id: <20210519183951.3946870-7-jsnow@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
This commit is contained in:
John Snow 2021-05-19 14:39:42 -04:00 committed by Markus Armbruster
parent 7c610ce6a9
commit 9cd0205d55
3 changed files with 10 additions and 8 deletions

View File

@ -78,7 +78,11 @@ class QAPISchemaParser:
self.docs.append(cur_doc)
continue
expr = self.get_expr(False)
expr = self.get_expr()
if not isinstance(expr, dict):
raise QAPISemError(
info, "top-level expression must be an object")
if 'include' in expr:
self.reject_expr_doc(cur_doc)
if len(expr) != 1:
@ -251,7 +255,7 @@ class QAPISchemaParser:
self.accept()
if key in expr:
raise QAPIParseError(self, "duplicate key '%s'" % key)
expr[key] = self.get_expr(True)
expr[key] = self.get_expr()
if self.tok == '}':
self.accept()
return expr
@ -270,7 +274,7 @@ class QAPISchemaParser:
raise QAPIParseError(
self, "expected '{', '[', ']', string, or boolean")
while True:
expr.append(self.get_expr(True))
expr.append(self.get_expr())
if self.tok == ']':
self.accept()
return expr
@ -278,9 +282,7 @@ class QAPISchemaParser:
raise QAPIParseError(self, "expected ',' or ']'")
self.accept()
def get_expr(self, nested):
if self.tok != '{' and not nested:
raise QAPIParseError(self, "expected '{'")
def get_expr(self):
if self.tok == '{':
self.accept()
expr = self.get_members()

View File

@ -1 +1 @@
non-objects.json:1:1: expected '{'
non-objects.json:1: top-level expression must be an object

View File

@ -1 +1 @@
quoted-structural-chars.json:1:1: expected '{'
quoted-structural-chars.json:1: top-level expression must be an object