Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2021-04-30' into staging

QAPI patches patches for 2021-04-30

# gpg: Signature made Fri 30 Apr 2021 12:42:32 BST
# gpg:                using RSA key 354BC8B3D7EB2A6B68674E5F3870B400EB918653
# gpg:                issuer "armbru@redhat.com"
# gpg: Good signature from "Markus Armbruster <armbru@redhat.com>" [full]
# gpg:                 aka "Markus Armbruster <armbru@pond.sub.org>" [full]
# Primary key fingerprint: 354B C8B3 D7EB 2A6B 6867  4E5F 3870 B400 EB91 8653

* remotes/armbru/tags/pull-qapi-2021-04-30: (25 commits)
  qapi/error.py: enable mypy checks
  qapi/error: Add type hints
  qapi/error.py: enable pylint checks
  qapi/error.py: move QAPIParseError to parser.py
  qapi/error: assert QAPISourceInfo is not None
  qapi/error: Make QAPISourceError 'col' parameter optional
  qapi/error: Use Python3-style super()
  qapi/error: Repurpose QAPIError as an abstract base exception class
  qapi/expr: Update authorship and copyright information
  qapi/expr.py: Use tuples instead of lists for static data
  qapi/expr.py: Add docstrings
  qapi/expr: Only explicitly prohibit 'Kind' nor 'List' for type names
  qapi/expr.py: enable pylint checks
  qapi/expr.py: Remove single-letter variable
  qapi/expr.py: Consolidate check_if_str calls in check_if
  qapi/expr.py: add type hint annotations
  qapi/expr.py: Modify check_keys to accept any Collection
  qapi/expr.py: Add casts in a few select cases
  qapi/expr.py: Check type of union and alternate 'data' member
  qapi/expr.py: move string check upwards in check_type
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell
2021-04-30 16:02:00 +01:00
14 changed files with 432 additions and 114 deletions
+2 -1
View File
@@ -34,7 +34,8 @@ from sphinx.errors import ExtensionError
from sphinx.util.nodes import nested_parse_with_titles
import sphinx
from qapi.gen import QAPISchemaVisitor
from qapi.schema import QAPIError, QAPISemError, QAPISchema
from qapi.error import QAPIError, QAPISemError
from qapi.schema import QAPISchema
# Sphinx up to 1.6 uses AutodocReporter; 1.7 and later
+29 -22
View File
@@ -1,7 +1,5 @@
# -*- coding: utf-8 -*-
#
# QAPI error classes
#
# Copyright (c) 2017-2019 Red Hat Inc.
#
# Authors:
@@ -11,15 +9,36 @@
# This work is licensed under the terms of the GNU GPL, version 2.
# See the COPYING file in the top-level directory.
"""
QAPI error classes
Common error classes used throughout the package. Additional errors may
be defined in other modules. At present, `QAPIParseError` is defined in
parser.py.
"""
from typing import Optional
from .source import QAPISourceInfo
class QAPIError(Exception):
def __init__(self, info, col, msg):
Exception.__init__(self)
self.info = info
self.col = col
self.msg = msg
"""Base class for all exceptions from the QAPI package."""
def __str__(self):
class QAPISourceError(QAPIError):
"""Error class for all exceptions identifying a source location."""
def __init__(self,
info: Optional[QAPISourceInfo],
msg: str,
col: Optional[int] = None):
super().__init__()
self.info = info
self.msg = msg
self.col = col
def __str__(self) -> str:
assert self.info is not None
loc = str(self.info)
if self.col is not None:
assert self.info.line is not None
@@ -27,17 +46,5 @@ class QAPIError(Exception):
return loc + ': ' + self.msg
class QAPIParseError(QAPIError):
def __init__(self, parser, msg):
col = 1
for ch in parser.src[parser.line_pos:parser.pos]:
if ch == '\t':
col = (col + 7) % 8 + 1
else:
col += 1
super().__init__(parser.info, col, msg)
class QAPISemError(QAPIError):
def __init__(self, info, msg):
super().__init__(info, None, msg)
class QAPISemError(QAPISourceError):
"""Error class for semantic QAPI errors."""
+369 -75
View File
File diff suppressed because it is too large Load Diff
-10
View File
@@ -3,16 +3,6 @@ strict = True
disallow_untyped_calls = False
python_version = 3.6
[mypy-qapi.error]
disallow_untyped_defs = False
disallow_incomplete_defs = False
check_untyped_defs = False
[mypy-qapi.expr]
disallow_untyped_defs = False
disallow_incomplete_defs = False
check_untyped_defs = False
[mypy-qapi.parser]
disallow_untyped_defs = False
disallow_incomplete_defs = False
+13 -1
View File
@@ -18,10 +18,22 @@ from collections import OrderedDict
import os
import re
from .error import QAPIParseError, QAPISemError
from .error import QAPISemError, QAPISourceError
from .source import QAPISourceInfo
class QAPIParseError(QAPISourceError):
"""Error class for all QAPI schema parsing errors."""
def __init__(self, parser, msg):
col = 1
for ch in parser.src[parser.line_pos:parser.pos]:
if ch == '\t':
col = (col + 7) % 8 + 1
else:
col += 1
super().__init__(parser.info, msg, col)
class QAPISchemaParser:
def __init__(self, fname, previously_included=None, incl_info=None):
+1 -3
View File
@@ -2,9 +2,7 @@
# Add files or directories matching the regex patterns to the ignore list.
# The regex matches against base names, not paths.
ignore-patterns=error.py,
expr.py,
parser.py,
ignore-patterns=parser.py,
schema.py,
+2 -2
View File
@@ -20,7 +20,7 @@ import re
from typing import Optional
from .common import POINTER_SUFFIX, c_name
from .error import QAPIError, QAPISemError
from .error import QAPISemError, QAPISourceError
from .expr import check_exprs
from .parser import QAPISchemaParser
@@ -875,7 +875,7 @@ class QAPISchema:
other_ent = self._entity_dict.get(ent.name)
if other_ent:
if other_ent.info:
where = QAPIError(other_ent.info, None, "previous definition")
where = QAPISourceError(other_ent.info, "previous definition")
raise QAPISemError(
ent.info,
"'%s' is already defined\n%s" % (ent.name, where))
@@ -0,0 +1,2 @@
alternate-data-invalid.json: In alternate 'Alt':
alternate-data-invalid.json:2: 'data' must be an object
@@ -0,0 +1,4 @@
# Alternate type requires an object for 'data'
{ 'alternate': 'Alt',
'data': ['rubbish', 'nonsense']
}
+2
View File
@@ -14,6 +14,7 @@ schemas = [
'alternate-conflict-string.json',
'alternate-conflict-bool-string.json',
'alternate-conflict-num-string.json',
'alternate-data-invalid.json',
'alternate-empty.json',
'alternate-invalid-dict.json',
'alternate-nested.json',
@@ -192,6 +193,7 @@ schemas = [
'union-clash-branches.json',
'union-empty.json',
'union-invalid-base.json',
'union-invalid-data.json',
'union-optional-branch.json',
'union-unknown.json',
'unknown-escape.json',
+2
View File
@@ -0,0 +1,2 @@
union-invalid-data.json: In union 'TestUnion':
union-invalid-data.json:2: 'data' must be an object
@@ -0,0 +1,6 @@
# the union data type must be an object.
{ 'union': 'TestUnion',
'base': 'int',
'discriminator': 'int',
'data': ['rubbish', 'nonsense']
}